TCP协议 及 TCP粘包现象
TCP,Transmission Control Protocol,传输控制协议。这是一个面向连接的传输层协议。与之相对的无连接协议为UDP,用户数据报协议。
传输层的基本数据单位为——报文。网络层——包。数据链路层为——帧。物理层——比特。
TCP提供面向连接的可靠服务,传送数据之前必须先建立连接,传送完毕要释放链接。
服务器端使用的端口号:熟知端口号——0~1023;登记端口号——1024~49151.
客户端使用的端口号——49152~65535。这种端口号仅在客户进程运行时才动态确定。当服务器进程收到客户端进程的报文时,就知道了客户进程使用的端口号。
TCP协议是点对点的,提供不丢失、不重复、无差错的可靠传输。
TCP提供全双工通信允许通信双方的进程在任何时候都能发送数据。两个进程都设有发送缓存和接收缓存。
TCP的可靠传输是建立在不可靠的IP层之上的,这很神奇。依靠的措施是——报文确认和超时重传。
1.TCP报文格式
图1-1 Tcp报文的首部与数据
序号。TCP是面向字节流的,TCP传送的每一个字节都有编号。
确认号(小写ack)。期望收到对方下一个报文段的数据部分第一个字节的编号。
数据偏移。指出本TCP报文段的数据部分距离初始部分有多远。实际上也就是首部的长度。
ACK。值为1时确认号才有效。也就是说,建立连接后所有的报文段都必须把ACK置为1。
PSH。若psh为1,报文段直接发送,不再等缓冲区满了再向下交付。
RST。复位标识。若TCP链接出现严重差错,则重连。
SYN。同步标识,若为1,表明这是连接报文或同意连接报文。
FIN。终止标识,表示释放一个连接。
接收窗口。告诉发送方自己接收区的缓存大小。
校验和。检验整个报文段。注意区分的是,IP数据报的校验和只检验IP数据报首部。
最大报文段长度MSS。指数据部分的最大长度,加上首部长度才是整个TCP报文段的最大长度。
2.TCP的拥塞控制
1.慢开始和拥塞避免。2.快重传和快恢复。
3.TCP的建立链接
图3-1 三次握手
4.TCP的连接释放
图4-1 四次握手
问:为什么断开连接需要4次握手呢?
答:tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据。
5.粘包现象
TCP粘包问题。
TCP提供的是可靠的字节流服务。假设TCP接收方是B,发送方是A。
理想情况下,B每次read的都是A每次write的内容,但事实不是这样的。
会出现A第一次发送(write)qwer这个字节流,第二次发送tyui;而B第一次读到(read)的是qwe,第二次read的是rt,第三次read的是yui这种情况。
为什么呢?
应用层的数据交给TCP,会被分割再包装成TCP报文,再加上下面IP层的缓冲区处理、网络拥塞等状况,就会发生上面的情况。
应对方法
应用层发送“你好”,假设对应的字节数组是[1,2,3,4],那么处理后交给TCP的是 [0,4,1,2,3,4],前两个byte固定放本次传输数据量的大小。TCP接收端再写一个相应的函数,依据长度提取字节就可以啦。
TCP提供的是可靠的字节流服务。假设TCP接收方是B,发送方是A。
理想情况下,B每次read的都是A每次write的内容,但事实不是这样的。
会出现A第一次发送(write)qwer这个字节流,第二次发送tyui;而B第一次读到(read)的是qwe,第二次read的是rt,第三次read的是yui这种情况。
为什么呢?
应用层的数据交给TCP,会被分割再包装成TCP报文,再加上下面IP层的缓冲区处理、网络拥塞等状况,就会发生上面的情况。
应对方法
应用层发送“你好”,假设对应的字节数组是[1,2,3,4],那么处理后交给TCP的是 [0,4,1,2,3,4],前两个byte固定放本次传输数据量的大小。TCP接收端再写一个相应的函数,依据长度提取字节就可以啦。
我的处理
亲测成功(测试中只有描述尺寸的头部 分两次 被read()到的情况没出现过)