TCP/IP底层原理

来源:互联网 发布:pdm产品数据管理软件 编辑:程序博客网 时间:2024/04/30 08:09
1.MTU(maximum transmission unit)
  
  MTU 最大传输单元,即在网络上传送的数据帧的最大大小,这是由硬件层规定的,位于协议层模型最低层。例如,以太网的MTU


为1500字节,老的SLIP链路通常使用296字节的MTU。IPv4要求最小的MTU为68字节,IPv6要求最小MTU为567字节。
  
  当一个IP层的数据包从某个接口发出,如果它的大小超过相应链路层的MTU, 则IP层将对其执行分片,且各分片到达目的地前不


会被重组。不同的网络之间MTU可能不同,IPv4主机对其产生的数据报执行分片,IPv4路由器对其转发的数据包也将执行分片;但是


IPv6只在数据报产生的主机执行分片,IPv6路由器对其转发的数据报不执行分片。
  
  IPv4头部的DF位(不分片)若被设置,则不管发送主机和转发路由器将都不能对本数据报分片,此时若发现一外出数据包超过其


外出链路MTU大小,则将在IP层产生一ICMPv4的“destination unreachable, fragmentation needed but DF bit set”(目的地不可


达,需分片但是DF位已被设置)的错误信息。
  
  因为IPv6路由器不执行分片,如果IPv6路由器收到一个超过其外出链路层MTU大小的数据报,它将产生一个ICMPv6的“packet too 


big”(分组太大)的错误信息。
  
  MTU发现技术(略)。
  
  IPv4和IPv6都规定了最小重组缓冲区大小(minimum reassembly buffer size):任何IPv4和IPv6的实现都必须支持的最小数据


报大小。IPv4----576字节,IPv6----1500字节。所以很多使用UDP的应用都尽量避免产生大于这个大小的数据报。
  
  2.MSS (Maximum Segment Size)
  MSS 最大段大小,TCP用于通告对方应该在分节中能够发送的最大数据大小。SYN分节带有MSS选项。MSS的目的是告诉对方自己的


重组缓冲区的大小的实际值,因为MSS的大小经常设置成 MTU大小 -(IP头部大小 + TCP头部大小), 所以避免了分片。
  
  TCP头部有16位的MSS选项,最大值为65535;IPv4数据报中最大的TCP 数据量为65495,即65535-IPv4头部20个字节和TCP头部的


20个字节。
  
  3.TCP数据发送
  每个TCP套接口有一个发送缓冲区,我们可以用SO_SNDBUF套接口选项来修改这一缓冲区大小( #include <sys/socket.h&


gt; int setsockopt(int sockfd, int optname, const void* optval, sockelen_t* optlen); )。当应用进程调用write时,内核


从应用进程的缓冲区向套接口的缓冲区拷贝数据,如果套接口缓冲区不够容纳应用进程的数据,则应用进程将阻塞在write调用处(


套接口默认设置为阻塞模式),直到应用进程缓冲区的所有数据都拷贝进入了套接口的缓冲区,write才返回,进程继续,但是这并


不表示对方的TCP已经收到数据。(send可以保证,建议使用send,sendto,sendmsg)
  
  TCP取套接口发送缓冲区的数据并发送给对方TCP, 只有等到收到了对方的ACK,本地TCP才能删除套接口发送缓冲区中已被确认的


数据(如果没有收到确认信息,TCP将自动重传数据并等待更长时间,在数次重传失败以后,TCP才放弃,重传花费的总时间传统上是


4~10分钟,与实现有关,同理,在应用程序端,用户缓冲区的数据也要等到TCP正确返回才能删除,即TCP协议中每一层都提供这种确


认保证,最大限度的提供可靠性)。——可靠性保证
  
  TCP以MSS大小或者更小的块(分节,每个分节按顺序给每个字节关联一个序号进行排序,如果这些分节没有按顺序到达,TCP将


根据他们的序号重新组合并抛弃重复序号的分节,从而最大限度的提供数据的完整性和正确性)将数据发给IP层(同时给每个数据块


加上TCP头部),其中的MSS是对方通知的,当对方未通知默认是536字节。IP给每个TCP分节安上IP头部构成数据报,并查找其目的IP


地址的路由表项以确定外出接口,然后把数据报传给相应的数据链路层。IP可能对数据报进行分片(是否大于MTU),再传给链路层


。但是因为MSS选项提供了避免分片的保证,而新的实现又有路径MTU发现功能,从而避免了在IP层的分片。每一个链路层都有一个输


出队列,如果输出队列满则丢弃分组,并沿协议栈向上返回一个错误到TCP层,TCP将在以后的某个时刻重传这个分节。
  
  4.TCP数据的接收
  TCP套接口的接收缓冲区的可用空间大小就是TCP通告另一端的窗口大小,所以TCP接收缓冲区不可能溢出,因为对方不会发出超


过所通告窗口大小的数据。这就是TCP的流量控制,如果对方无视窗口大小发送了超过窗口大小的数据,接收方TCP将丢弃它。
  
  TCP接收缓冲区大小 对于不同的实现,缺省值的大小可以有很大差别,一般为8192~61440字节之间。#include&


lt;sys/socket.h> int setsockopt(int sockfd, int level, int optname, const void* optval, socklen_t* optlen); 可利


用SO_RCVBUF设置接收缓冲区大小。设置缓冲区大小的操作应该尽量在所有操作之前,因为TCP在建立连接时会通过SYN互换双方的窗


口规模。对于一个客户端,SO_RCVBUF选项必须在connect之前设置,而服务器端则必须在listen之前设置。套接口的缓冲区的大小总


是由新创建的已连接套接口从监听套接口那继承来的。
  
  TCP的套接口缓冲区大小必须是连接的MSS的三倍以上。TCP套接口缓冲区的大小还必须是连接的MSS的偶数倍。
原创粉丝点击