TCP/IP详解 第十二章(1) TCP传输控制协议

转载请声明博主:https://mp.csdn.net/console/editor/html/106495203

一、TCP的服务

  

1、尽管TCPUDP都使用相同的网络层(IP),TCP却向应用层提供与UDP完全不同的服务,TCP提供一种面向连接的可靠的字节流服务

2TCP充分实现了数据传输时各种控制功能,可以进行丢包的重发控制,还可以对次序乱掉的分包进行顺序控制。而这些在UDP中都没有。此外,TCP作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输

 

二、TCP的首部与UDP首部对比

          

思考:tcpudp最大最小的数据长度?https://blog.csdn.net/caofengtao1314/article/details/106495232

TCP头部8位字段

1CWR—拥塞窗口减(发送方降低它的发送速率)

2ECE—ECN回显(发送方收到了一个更早的拥塞通知)

3URG—紧急(紧急指针字段有效很少被使用)

4ACK—确认(确认号字段有效连接建立以后一般都是启用状态)

5PSH—推送(接收方应尽快给应用程序传送这个数据---没被可靠地实现和应用)---基本应用层无法控制,网络层直接控制为PSH

6RST—重置连接(连接取消,经常是因为错误)

7SYN—用于初始化一个连接的同步序号

8FIN—该报文段的发送方已经结束向对方发送数据

思考:URGPSH的区别?https://blog.csdn.net/caofengtao1314/article/details/106495269

三、TCPUDP套接字编程对比

TCP: 


TCP编程的服务器端一般步骤是: 
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt(); * 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind(); 
  4、开启监听,用函数listen(); 
  5、接收客户端上来的连接,用函数accept(); 
  6、收发数据,用函数send()recv(),或者read()write(); 
  7、关闭网络连接; 
  8、关闭监听; 

TCP编程的客户端一般步骤是: 
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt();* 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 
  4、设置要连接的对方的IP地址和端口等属性; 
  5、连接服务器,用函数connect(); 
  6、收发数据,用函数send()recv(),或者read()write(); 
  7、关闭网络连接;

UDP:

与之对应的UDP编程步骤要简单许多,分别如下: 
  
UDP编程的服务器端一般步骤是: 
  
1、创建一个socket,用函数socket(); 
  
2、设置socket属性,用函数setsockopt();* 可选 
  
3、绑定IP地址、端口等信息到socket上,用函数bind(); 
  4、循环接收数据,用函数recvfrom(); 
  5、关闭网络连接; 
UDP编程的客户端一般步骤是: 
  
1、创建一个socket,用函数socket(); 
  
2、设置socket属性,用函数setsockopt();* 可选 
  
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 
  
4、设置对方的IP地址和端口等属性
  5、发送数据,用函数sendto(); 
  6、关闭网络连接;

思考:可不可以从编程模型看到udptcp有无链接的区别?

 

四、TCPUDP粘包

socket网络程序中,TCPUDP分别是面向连接和非面向连接的。

TCPsocket编程,收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制

对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了

举个栗子

 

 

 

我们连续发送三个数据包,大小分别500,  1200 ,5000 ,这三个数据包,都已经到达了接收端的网络堆栈中。

使用UDP协议,不管应用层使用多大的接收缓冲区去接收数据,我们必须有三次接收动作,才能够把所有的数据包接收完.

思考:不管应用层使用多大的缓冲区?

如果缓冲区为100字节,那么第一次读100字节,那基于链式传输的就会丢失剩下的400字节,第二次读取100字节,会丢失剩下的1100字节数据。第三次读取100字节会丢失剩下的4900字节数据。

思考:如果缓冲区为2000字节呢?如果为5000字节呢?

如果缓冲区为2000字节,那么第一次读500字节。第二次读取1200字节数据 。第三次读取2000字节会丢失剩下的3000字节数据。

如果缓冲区为5000字节,那么第一次读500字节。第二次读取1200字节数据 。第三次读取5000字节。

如果缓冲区为10000字节,那么第一次读500字节。第二次读取1200字节数据 。第三次读取5000字节。

使用TCP协议,应用层只要把接收的缓冲区大小设置6700以上,我们就能够一次把所有的数据包接收下来只需要有一次接收动作。实际测试在server accept成功以后,休眠10秒然后才读取客户端的数据,结果一次读取完成。

应用层如果将缓冲区大小设置为100那么就需要读取67次才可以读取完,实际测试总共读取了67次,如果调整各种接收方式可能会出现大于读取67次的情况,但是读取的总得数量仍然是6700个字节,那是因为TCP的拥塞控制和滑动窗口在作怪,。

UDP不存在粘包问题,是由于UDP发送的时候,没有经过Negal算法优化,不会将多个小包合并一次发送出去。另外,在UDP协议的接收端,采用了链式结构来记录每一个到达的UDP包,这样接收端应用程序一次recv只能从socket接收缓冲区中读出一个数据包。也就是说,发送端send了几次,接收端必须recv几次(无论recv时指定了多大的缓冲区)

      TCP由于采用Negal算法优化,并且采用字节流式传输,因此存在粘包的问题。

总结: TCP存在粘包的问题,UDP不存在粘包的问题。

TCPUDP分片

全球互联网  mtu值统计

参考TCP/IP详解卷一,第一版 115页 做的全球互联网实验     

       作为一个实验,我们多次运行修改以后的traceroute程序,目的端为世界各地的主机,可以到达15个国家(包括南极洲),使用了多个跨大西洋和跨太平洋的链路。但是,在这样做之前,作者所在子网与路由器netb之间的拨号SLIP链路MTU增加到1500与以太网相同。   

        18次运行当中,只有其中2次发现的路径MTU小于1500。其中一个跨大西洋的链路MTU值为572,而路由器返回的的是新格式的ICMP差错报文。另外一条链路,在日本的两个路由器之间,不能处理1500字节的数据帧,并且路由器没有返回新格式的ICMP差错报文。把MTU值设成1006则可以正常工作。     

        这个实验可以读出结论,现在许多但不是所有的广域网都可以处理大于512自己的分组,利用路径MTU发现机制,应用程序就可以充分利用更大的MTU来发送报文。     对于MTU值,要求主机必须能够接收至少576字节的IP数据报。在许多UDP应用程序设计中,其应用程序数据被限制成512字节或更小,因此比这个限制值小。当然,我们可以通过分析很多路由协议(DNS TFTP BOOTP SNMP)总是发送每份小于512字节的数据。

最大的UDP数据报长度:

      理论上,IP数据报的最大长度65535字节,这是由于IP首部16比特总长度字段所限制的。去除20字节IP首部和8字节的UDP首部,UDP数据报中用户数据的最大长度为65507,实际使用socket 编程调用sendto函数也是这样,超过这个值会出现sendto失败。

最大的TCP数据报长度:

      使用send函数目前不清楚为send多大就可以失败,但是根据网络定义,这个值完全是根据不同的平台不同的内核实现的。

      在抓包过程中影响TCP报文长度的一个值为MSS(最大报文长度)表示TCP传往另一端的最大数据块的长度。当一个连接监理师,连接的双方都要通告各自的MSS。最终的IP数据报通常是40个字节 ,即MSS值最大为1460字节。

对于TCP来说,它是尽量避免分片的,为什么?因为如果在IP层进行分片了话,如果其中的某片的数据丢失了,对于保证可靠性的TCP协议来说,会增大重传数据包的机率,而且只能重传整个TCP分组。

        如何避免分片?
       3次握手中,除了确认SYN分节外,通信的两端还进行协商了一个值,MSS,这个值用来告诉对方,能够发送的TCP分节的大小。这个值一般是取其链路

层的MTU大小减去TCP头部大小和IP头部的大小。MSS=MTU-TCP头部大小-IP头部大小MTU的值可以通过询问链路层得知

     

      当两端确认好MSS后进行通信,当TCP层往IP层传输数据时,如果TCP层缓冲区的大小大于MSS,那么TCP层都会将其发送缓冲区中的数据切分成MSS大小的分组进行传输,由于MSS是通过MTU减去TCP头部大小和IP头部的大小计算得出的,MSS肯定比MTU小,那么到IP层的时候就可以避免IP层的分片。

   文献【1992】提供了再一个繁忙的NFS服务器上所发生的不同校验和和差错的统计结果,时间持续了40天。

从统计结果可以看出,不要完全相信数据链路(如以太网,令牌环等)CRC校验。应该始终打开端到端的校验和功能。而且,如果你的数据很有价值,也不要完全相信UDPTCP的校验和,因为这些都只是简单的校验和,不能检测出所有可能发生的差错。

六、TCPUDP的区别

七、TCPUDP在实际项目中的应用

udp组播

1、对于网络层校验的问题加入了TAG+CRC32校验+data_len,保证数据头尾的完整性

2、基于UDP的数据最大长度,LXC项目转发效率考虑

     ts 长度188 字节

     lxc_dtv  à  lxc_server à lxc_proxy

        经过了3次转发,200msdemux读出的数据长度为48128也就是188字节的256倍,而基于目前加密的考虑和mtu的考虑将每次数据转发出去的长度定义为188*4那么经过3次转发需要,总共需要转发3*25=75次,再加上6个线程,基本200ms,需要转发75*6=450次。太浪费CPU了。

      解决办法,从最大长度入手,lxc内部直接发送48128*5/4的长度,然后到proxy才按照一个合理的值将数据分成小段发送出去。

udp通信

1、对于网络层校验的问题加入了数据长度,对于互联网保证数据完整性很差

2、为了防止分片将数据长度设计不超过1472,但是基于互联的mtu值考虑,最好小于576-20-8=548

TCP通信

1、对于粘包的问题和网络层校验的问题加入TAG+CRC32校验+data_len,保证数据头尾的完整性

2、为了防止分片将数据长度设计小于MSS

TCP连接的建立与终止

三次握手

 

四次挥手

 

TCP半关闭

 

shoutdown函数可以实现半关闭,

close函数实现的是两端都关闭

TCP同时打开与关闭

 

十一TCP状态转换图

引导:防火墙如何固定TCP客户端与服务端

 

十二、TCP复位报文段

情况1:到不存在的端口的连接请求

 

情况2:异常终止一个连接

 

情况3:检测半打开连接

 

情况4:时间等待错误

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TCP/IP详解 卷1:协议(原书第2版)PDF》是由美国计算机科学家 Douglas Comer 所著的一本关于 TCP/IP 协议的经典教材。该书详细介绍了 TCP/IP 协议栈的各个层级以及其应用和实际场景。 这本书主要分为两个部分:第一部分是对 TCP/IP 协议栈的介绍和分析,包括网络层、传输层、应用层等各个方面的内容。第二部分是对 TCP/IP 协议的应用和实践指导,包括网络管理、安全性、多媒体和网络编程等内容。 通过阅读这本书,读者可以深入了解 TCP/IP 协议栈的工作原理、网络通信的基本概念和技术细节。书中提供了大量的实践案例和代码示例,可以帮助读者理解和应用 TCP/IP 协议栈。 《TCP/IP详解 卷1:协议(原书第2版)PDF》是一本权威且经典的教材,被广泛用于计算机网络和通信领域的学习和研究。无论是网络工程师、系统管理员、还是对计算机网络感兴趣的人都可以从中获得深入的知识和实践经验。 该书在网络技术的发展历程中具有重要的地位和影响力,它不仅仅是一本理论教材,更是对 TCP/IP 协议的全面解析和实践指南。对于想要深入掌握和理解 TCP/IP 协议栈的人来说,这本书是一本必不可少的参考资料。 总而言之,《TCP/IP详解 卷1:协议(原书第2版)PDF》是一本经典且权威的 TCP/IP 协议教材,适合各个层次的读者阅读和学习。无论是初学者还是专业人士,都可以通过阅读这本书,深入理解和应用 TCP/IP 协议栈。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值