开发者社区> demon_coffee> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

TCP通信实现

简介: [1] tcp通信原理     1. 建立连接     2. 通信     3. 断开连接     [2] TCP实现流程     1. 头文件         #include         #include         #include     2.
+关注继续查看
[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"

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
一文讲透TCP三次握手到底怎么实现的(上)
一文讲透TCP三次握手到底怎么实现的
46 0
一文讲透TCP三次握手到底怎么实现的(下)
一文讲透TCP三次握手到底怎么实现的
30 0
详解企业获客利器:阿里云通信如何助力企业实现用户增长?
2021上云采购季火热进行中,云栖号同期为用户带来了很多精彩线上直播。本次,来自阿里云通信智能消息团队的产品运营胡超分享了《助力企业客户实现用户增长的获客利器》主题演讲,通信平台是企业触达用户的主要方式,如何借助通信能力提升触达效率,获得用户增长?本次分享胡超将为用户讲解阿里云通信创新产品的行业应用。
312 0
朋友阿里面试题之 TCP/IP,回去等通知吧
最近和一同学聊天,他想换工作,然后去面了一家大厂。当时,他在简历上写着精通TCP/IP,本着对TCP协议稍有了解,面试官也不会深问的想法,就写了精通二字。没想到,大意了.
3600 0
dump_stack 实现分析【转】
转自:http://kernel.meizu.com/2017/03/18-40-19-dump_stack.html 1 简介 说起 dump_stack() ,相信从事 Linux 内核或者驱动相关开发的同行对于此函数肯定不陌生。
1420 0
TCP通信(二)
package cn.com; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; //TCP服务端 //关于TCP的客户端和服务端的比喻(我的理解): //比如在很大的宾馆的前台,有许许许多多电话,这个前台就是一个TCP服务端。
727 0
+关注
demon_coffee
全栈工程师(正在进行中~~~)
83
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载