博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TCP通信实现
阅读量:5779 次
发布时间:2019-06-18

本文共 3160 字,大约阅读时间需要 10 分钟。

[1] tcp通信原理
    1. 建立连接
    2. 通信
    3. 断开连接
   
[2] TCP实现流程
    1. 头文件
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
    2. 数据结构
    3. 实现流程(函数)
       (1) 服务端
           1. 创建监听socket                                          买手机
              /*
               * @param[in] domain 通信领域
               *                  @li AF_UNIX, AF_LOCAL 本机通信
               * @li AF_INET ipv4
               *                  @li AF_INET6 ipv6
               * @li AF_PACKET         底层数据包
               * @param[in] type 套接字类型
               * SOCK_STREAM           流式套接字(TCP)
               * SOCK_DGRAM            报文套接字(UDP)
               * SOCK_RAW              原始套接字(IP、ICMP)
               * @param[in] protocol 指定使用协议,通常是0
               * @return 文件描述符(套接字)
               * @li -1 错误(错误码见errno)
               */
              int socket(int domain, int type, int protocol);
           2. 绑定ip地址(本机)和端口(自己的端口)到监听socket          放SIM卡
              /*
               * @brief 绑定ip地址(本机的)和端口(自己的)到socket
               * @param[in] sockfd  套接字
               * @param[in] addr 地址(通信类型、ip地址和端口号)
               * @param[in] addrlen addr的字节数
               * @return @li 0 绑定成功
               * @li -1 错误(错误码见errno)
               */
              int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
           3. listen(将socket设置为监听模式)                          开机
              /*
               * @brief 将socket设置为监听模式
               * @param[in] sockfd  套接字
               * @param[in] backlog 设置listen队列的最大连接请求个数
               * @return @li 0 成功
               * @li -1 错误(错误码见errno)
               */
              int listen(int sockfd, int backlog);
           4. accept(接收客户端连接, 创建客户端socket)                接通
              /*
               * @brief 接收客户端连接, 创建跟客户端连接的socket
               * @param[in] sockfd  监听套接字
               * @param[out] addr 客户端地址(ip地址和端口)
               * @param[in | out] addrlen 输入地址缓存的字节数,输出实际地址的字节数
               * @return 文件描述符(客户端套接字)
               * @li -1 错误(错误码见errno)
               * @notes listen请求队列为空时,在阻塞模式下,本函数会阻塞
               */
              int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
           5. 利用客户端socket接收/发送数据                           说话
              /*
               * @brief 发送数据(写数据到发送缓冲区)
               * @param[in] sockfd  客户端套接字
               * @param[in]  buf 要发送的数据
               * @param[in]       len    数据长度
               * @param[in] flags 一般为0
               * @return 成功发送的字节数
               * @li -1 错误(错误码见errno)
               * @notes 一个字节都无法发送时,在阻塞模式下,本函数会阻塞
               *                  send(sockfd, buf, len, 0) <===> write(sockfd, buf, len);
               */
              ssize_t send(int sockfd, const void *buf, size_t len, int flags);
              /*
               * @brief 接收数据(读取数据从接收中缓冲区)
               * @param[in] sockfd  客户端套接字
               * @param[out] buf 放置数据的缓冲
               * @param[in]       len    缓冲区的字节数
               * @param[in] flags 一般为0
               * @return 成功读取的字节数
               * @li -1 错误(错误码见errno)
               * @notes 一个字节都无法接收时,在阻塞模式下,本函数会阻塞
               *                  recv(sockfd, buf, sizeof(buf), 0) <===> read(sockfd, buf, sizeof(buf));
               */
              ssize_t recv(int sockfd, void *buf, size_t len, int flags);
           6. close客户端socket                                       挂机
           7. close监听socket                                         关机
              int close(int fd);
              /*
               * @brief 关闭套接字
               * @param[in] sockfd  套接字
               * @param[in]    how 如何关闭?
               * @li SHUT_RD 关闭读
               * @li SHUT_WR 关闭写
               * @li SHUT_RDWR 关闭读写
               * @return @li 0 成功
               * @li -1 错误(错误码见errno)
               */
              int shutdown(int sockfd, int how);
       (2) 客户端
           1. 创建socket
           2. 绑定ip地址(本机)和端口(自己的端口)到socket(可选)
           3. 建立连接(connect)
              /*
               * @brief 连接服务端
               * @param[in] sockfd  套接字
               * @param[in]  addr  服务端地址(ip和端口)
               * @param[in]       addrlen 地址字节数
               * @return @li 0                 成功
               * @li -1 错误(错误码见errno)
               * @notes 正在连接时,在阻塞模式下,本函数会阻塞,但阻塞有超时时间
               */
              int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
           4. 发送/接收数据
           5. 关闭socket
[3] udp聊天室
    1. 简单的多人聊天
       见《4.udp聊天室》
       
    2. 标准聊天
       (1) 登陆(功能 名字)
       (2) 聊天(功能 内容)
       (3) 退出(功能)
       
       1. 制定协议
          打包(数据组合)   1. 结构体     2. 按顺序放数据到缓存
         
          1. 结构体分析
             typedef struct {
               // char c;
               // 中间会空3个字节
               int func;
               char c;
               char *p;
             } PROL ;
                    客户端            服务器      错误原因                                        解决
           字节序    小端             大端       func会错误,func有四个字节,字节顺序正好相反     统一使用大端(htonl/ntohl htons/ntohs)
           位数      32bit            64bit      机器理解int类型的时候,位数不同                  系统没有提供统一方法,程序自己保证位数相同
           对齐      32bit            64bit      因为结构体程序对齐,很可能导致中间,空闲的字节   认真设计结构体,是它尽量不出现因为需要对齐,而空出内存
                                                 数,不相同而导致解析错误  
           对于初学者,如果需要考虑数据传输完全正确,不要使用结构体。
           
          2. 按顺序放数据到缓存
             最简单的方法,保证协议中的数据都是以字节为单位
             
             300        "300"
             2.7        "2.7"

转载地址:http://ayyyx.baihongyu.com/

你可能感兴趣的文章
阿里架构师:程序员必须掌握的几项核心技术能力
查看>>
程序员常用的六大技术博客类
查看>>
vue中动画的实现的几种方式
查看>>
Iceworks 2.8.0 发布,自定义你的 React 模板
查看>>
胖哥学SpringMVC:请求方式转换过滤器配置
查看>>
Kotlin 更加优雅的 Builder - 理解 with
查看>>
前端日拱一卒D6——字符编码与浏览器解析
查看>>
python学习笔记- 多线程
查看>>
换一种思维看待PHP VS Node.js
查看>>
举重若轻的人人车移动端数据平台
查看>>
Oracle回应用户锁定,自治数据库是更好选择
查看>>
深入理解浏览器的缓存机制
查看>>
使用 Swift 3.0 操控日期
查看>>
微软向Linux社区开放60000多项专利:对开源微软是认真的
查看>>
版本控制、Git及其在企业中的应用
查看>>
Ruby开发者已可通过Fog管理Microsoft Azure服务
查看>>
《Doing It - Management 3.0 Experiences》作者访谈
查看>>
基于 Bitbucket Pipeline + Amazon S3 的自动化运维体系
查看>>
Hoshin Kanri在丰田的应用
查看>>
又拍云沈志华:如何打造一款安全的App
查看>>