网站建设销售员工作内容,北京网站制作公司报价,优秀个人网站推荐,wordpress站群软件目录
1、TCP编程流程 2、粘包 1、TCP编程流程 socket() 是创建套接字#xff0c;返回值为监听套接字描述符#xff0c;有了套接字才能通过网络进行数据的传输。创建套接字的参数要指定服务类型#xff0c;TCP协议使用的是流式服务#xff08;SOCK_STREAM#xff09;。
b…目录
1、TCP编程流程 2、粘包 1、TCP编程流程 socket() 是创建套接字返回值为监听套接字描述符有了套接字才能通过网络进行数据的传输。创建套接字的参数要指定服务类型TCP协议使用的是流式服务SOCK_STREAM。
bind() 是指定套接字使用的IP和端口。IP地址 是自己主机的地址。端口 是一个16位整型值 一般0~1024为知名端口一般用户不能随便使用1024~4096为保留端口一般不使用4096以上为临时端口可以使用。在Linux系统上1024以内的端口号只有root用户可以使用。
listen() 是创建监听队列。监听队列有两种一个是存放未完成三次握手的连接一种是存放已完成三次握手的连接。该函数的第二个参数在Linux系统上是指已完成三次握手队列的长度在Unix系统上是未完成和已完成三次握手队列总和的大小。
accept() 是处理放在 listen() 创建的已完成三次握手队列中的连接。每处理一个连接accept()返回一个该连接对应的连接套接字描述符如果已完成三次握手队列为空则accept阻塞。 connect() 一般由客户端程序执行需要指定连接的服务端的IP和端口。该方法执行后会进行三次握手建立连接
三次握手建立连接 send() 是用来向TCP连接的对端发送数据。send()执行成功说明成功将数据写入发送端的发送缓冲区中并不能说明已经发到对端。返回值为实际写入发送缓冲区的数据长度。
recv() 是用来接收TCP连接的对端发送的数据。recv()从自己的接收缓冲区中读取数据如果接收缓冲区中没有数据就会阻塞。返回值为实际读取的字节数。
recv()返回值为0是对端关闭TCP连接的唯一标识。
close() 可用来关闭文件的该处用于关闭套接字和TCP连接。
关闭TCP链接自己端执行该方法后在对端未执行close()时进行两次挥手此时处于半连接状态当对端也执行close()后再进行后两次挥手最终完成四次挥手。
四次挥手断开连接 2、粘包
对6.2服务端代码中的recv()函数的参数从127改为1即一次recv一个字符。
客户端发送一个 hello 服务端将会把hello每个字符换行打印一次客户端收到一个 ok 当客户端再发送数据后将会收到四个 ok 。如下图 原因首先明确程序的循环运行速度要小于服务端将数据从其发送缓冲区传递到客户端的接收缓冲区。recv()和send()都是从接收缓冲区和发送缓冲区中读取数据并不意味着把数据发给对方或者从对方处接收到数据。
当服务端recv()第一个字符 ‘h’ 后此时客户端的recv()正处于阻塞状态客户端的接收缓冲区为空send()一个 ok 到发送缓冲区并传递给客户端的接收缓冲区还没等到服务端recv()第二个字符 ‘e’ 后send()第二个 ok 客户端就已经recv()了其接收缓冲区中的 “ok” 此时客户端的接收缓冲区只有一个 “ok” 。客户端recv()后阻塞在fgets()函数处等待输入数据。等待过程中服务端也已经将剩下的四个字符对应的四个 ok 陆陆续续发送到客户端的接收缓冲区中当客户端刚recv()第二个数据后就会立即读取接收缓冲区中的四个 ok 将其打印出来。
查看缓冲区的数据字节大小命令netstat -natp 出现这种数据粘连在一起无法区分第几次发送的情况即为粘包。
粘包的概念TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包
产生粘包的原因
1、TCP是基于字节流的虽然应用层和传输层之间的数据交互是大小不等的数据块但是TCP把这些数据块仅仅看成一连串无结构的字节流没有边界 2、在TCP的首部没有表示数据长度的字段基于上面两点在使用TCP传输数据时才有粘包或者拆包现象发生的可能。
粘包/拆包发生的原因
发生TCP粘包或拆包有很多原因现列出常见的几点 1、要发送的数据大于TCP发送缓冲区剩余空间大小将会发生拆包。 2、待发送数据大于MSS最大报文长度TCP在传输前将进行拆包。 3、要发送的数据小于TCP发送缓冲区的大小TCP将多次写入缓冲区的数据一次发送出去将会发生粘包。 4、接收数据端的应用层没有及时读取接收缓冲区中的数据将发生粘包。
TCP 字节流的特点发送端执行的写操作次数和接收端执行的读操作次数之间没有任何数量关系应用程序对数据的发送和接收是没有边界限制的。 粘包对于数据下载没有影响只需要将数据全部收到就可以而在交互时需要发送次数与接收次数对应。
粘包的简单解决办法
1、发送端给每个数据包添加包首部首部中应该至少包含数据包的长度这样接收端在接收到数据后通过读取包首部的长度字段便知道每一个数据包的实际长度了。
2、在数据前后加上标志对方接收到数据后进行检查数据是否完整。3、发送端将每个数据包封装为固定长度不够的可以通过补0填充这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。