传输层TCP协议——传输控制协议(TCP)

来源:互联网 发布:笔记本电脑连不上网络 编辑:程序博客网 时间:2024/06/15 13:36

TCP(即传输控制协议):是一种面向连接的传输层协议,它能提供可靠性通信(即数据无误,数据无丢失,数据无失序,数据无重复到达的通信)

  • TCP提供客户与服务器之间的连接。TCP客户先与某个给定服务器建立一个连接,再跨该连接与那个服务器交换数据,然后终止这个连接。
  • TCP提供可靠性。当TCP向另一端发送数据时,它要求对端返回一个确认。如果没有收到确认,TCP就自动重传数据并等待更长时间。在数次重传失败后,TCP才放弃。TCP提供的是数据的可靠递送或故障的可靠通知。
  • TCP含有用于动态估算客户与服务器之间的往返时间(round-trip time,RTT)的算法,以便它知道等待一个确认需要多少时间。RTT在一个局域网上大概是几毫秒,跨越一个广域网可能是数秒钟。
  • TCP通过对所发送的数据中每个字节关联一个序列号来进行排序。假设一个应用写2048字节到一个TCP套接字,导致TCP发送2个分节(分节是TCP传递给IP的数据单元):第一个分节所含数据的序列号为1~1024,第二个分节所含数据的序列号为1025~2048。如果这些分节非顺序到达,接收端TCP将先根据它们的序列号重新排序,再把结果数据传递给接收应用。如果接收端TCP接收到来自对端的重复数据(对端认为已丢失并因此重传,而这个分节并没有真正丢失,只是网络通信过于拥挤),它可以(根据序列号)判定数据是重复的,从而丢弃重复数据。
  • TCP提供流量控制(flow control)。TCP是一个字节流协议,没有任何记录边界。TCP总是告知对端在任何时刻它一次能够从对端接收多少字节的数据,这称为通告窗口(advertised window)。在任何时刻,该窗口指出接收缓冲区中当前可用的空间量,从而确保发送端发送的数据不会使接收缓冲区溢出。该窗口时刻动态变化:当接收到来自发送端的数据时,窗口大小就会减小;当接收端应用从缓冲区中读取数据时,窗口大小就会增大。当TCP对应某个套接字的接收缓冲区已满,通告窗口大小减小到0,导致它必须等待应用从该缓冲区读取数据时,方能从对端再接收数据。
  • TCP连接是全双工的(full-duplex)。这意味着在一个给定的连接上,应用可以在任何时刻,在进出两个方向上既发送数据又接收数据。因此,TCP必须为每个数据流方向跟踪诸如序列号和通告窗口大小等状态信息。
适用情况:
适合于对传输质量要求较高,以及传输大量数据的通信
在需要可靠数据传输的场合,通常使用TCP协议

MSN/QQ等即时通信软件的用户登录账户管理相关的功能通常采用TCP协议



1)TCP数据包结构


  • 源始端口(Source Port):16位,标识源端应用进程。范围0-65535。
  • 目的端口(Destination Port ):16位,标识源端应用进程。范围0-65535。
  • 数据序号(Sequence Number):32位,TCP连接中为传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
  • 确认序号(Acknowledgment Number):32位,用来确认本端TCP实体已经接收到的数据,其值表示期待对端发送的下一个字节的序号,实际上告诉对方,在这个序号减1以前的字节已正确接收。
  • 偏移(Data Offset):4位,表示以32位字为单位的TCP分组头的总长度,用于确定用户数据区的起始位置。
  • 保留(Reserved):6位,未使用,应置零。
  • 紧急比特URG:当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。
  • 确认比特ACK:当ACK=1时,确认号字段有效。当ACK=0时,确认号无效。
  • 推送比特PSH:Push操作。TCP分组长度不定,为提高传输速率,往往要收集到足够的数据后才发送。这种方式不适合实时性要求很高的应用。当PSH=1时,TCP提供“Push”操作,以强迫传输当前的数据,不必等待缓冲区满才传输。
  • 复位比特RST:当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。
产生RST的三个条件:
SYN到达目的地某端口,然而该端口上没有正在监听的服务器。
TCP想取消一个已有连接
TCP接收到一个根本不存在的连接上的分节。
  • 同步比特SYN:同步比特SYN置为1,就表示这是一个连接请求或连接接受报文。
每一个SYN可以含有多个TCP选项:
MSS选项:发送SYN的TCP一端使用本选项通告对端它的最大分节大小MSS(maximum segment size)。即它在本连接的每个TCP分节中愿意接受的最大数据量。MSS的目的是告诉对端其重组缓冲区大小的实际值,从而试图避免分片。MSS经常设置成MTU减去IP和TCP首部的固定长度。在以太网(MTU=1500)中使用IPv4的MSS值为1460(1500-20(IPv4首部-20(TCP首部) ),使用IPv6的MSS值为1440(1500-40(IPv6首部)-20(TCP首部))。发送端TCP使用接收端的MSS值作为所发送分节的最大大小。TCP_MAXSEG套接字选项提取和设置这个TCP选项。
窗口规模选项:TCP连接任何一端能够通告对端的最大窗口大小是65535,因为在TCP首部中相应的字段占16位。然而在已普及的高速网络连接(45Mbit/s或更快)或长延迟路径(卫星链路)要求有更大的窗口以获得尽可能大的吞吐量。此选项指定TCP首部中的通告窗口必须扩大(即左移)位数(0~14),所提供的最大窗口接近1GB(65535*214)。在一个TCP连接上使用窗口规模的前提是它的两个端系统必须都支持这个选项。SO_RCVBUF套接字选项影响这个TCP选项。
时间戳选项:这个TCP选项对于高速网络连接是必要的,它可以防止由失而复现的分组(由暂时的路由原因造成的迷途的分组。当路由稳定后,它们又会正常到达目的地,其前提是它们在此前尚未被路由器丢弃)可能造成的数据损坏。
  • 终止比特FIN:用来释放一个连接。当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
  • 窗口字段(Window):16位,窗口字段用来控制对方发送的数据量,单位为字节。TCP连接的一端根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方以确定对方的发送窗口的上限。
  • 包校验和(Checksum):16位,包括首部和数据这两部分。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。
  • 紧急指针(Urgent Pointer):16位,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。
  • 可选选项(Options):24位,TCP首部可以有多达40字节的可选信息,用于把附加信息传递给终点,或用来对齐其它选项。 
  • 填充(Padding):8位,为了使整个首部长度是32位的整数倍。
  • 用户数据(data)

2)TCP结构体定义
usr/src/linux-2.6.19/include/linux/tcp.h
struct tcphdr {    __be16 source;//源始端口    __be16 dest;//目的端口    __be32 seq;//数据序号    __be32 ack_seq;//确认序号#if defined(__LITTLE_ENDIAN_BITFIELD)    __u16res1:4,//保留            doff:4,//偏移            fin:1,            syn:1,            rst:1,            psh:1,            ack:1,            urg:1,            ece:1,            cwr:1;#elif defined(__BIG_ENDIAN_BITFIELD)    __u16doff:4,            res1:4,            cwr:1,            ece:1,            urg:1,            ack:1,            psh:1,            rst:1,            syn:1,            fin:1;#else#error "Adjust your <asm/byteorder.h> defines"#endif    __be16 window;//窗口字段    __be16 check;//包校验和    __be16 urg_ptr;//紧急指针};

3) TCP输出
某个应用进程写数据到一个TCP套接字中时发生的步骤:


每一个TCP套接字有一个发送缓冲区,套接字选项SO_SNDBUF更改该缓冲区的大小。
当某个应用进程调用write时,内核从该应用进程的缓冲区中复制所有数据到所写套接字的发送缓冲区。如果该套接字的发送缓冲区容不下该应用进程的所有数据(或是应用进程的缓冲区大于套接字的发送缓冲区,或是套接字的发送缓冲区中已有其他数据),该应用进程将被投入睡眠。假设套接字是阻塞的(默认设置),内核将不从write系统调用返回,直到应用进程缓冲区中的所有数据都复制到套接字发送缓冲区。因此,从写一个TCP套接字的write调用成功返回仅仅表示可以重新使用原来的应用进程缓冲区,并不表明对端的TCP或应用进程已接收到数据。
本端的TCP提取套接字发送缓冲区中的数据并把它发送给对端TCP,其过程基于TCP数据传送的所有规则。对端TCP必须确认收到的数据,伴随来自对端的ACK的不断到达,本端TCP至此才能从套接字发送缓冲区中丢弃已确认的数据。TCP必须为已发送的数据保留一个副本,直到它被对端确认为止。
  • 本端TCP以MSS大小的或更小的块把数据传递给IP,同时给每个数据块安上一个TCP首部以构成TCP分节,其中MSS或是由对端通告的值,或是536(若对端未发送一个MSS选项)。
  • IP给每个TCP分节安上一个IP首部以构成IP数据报,并按照其目的IP地址查找路由表项以确定外出接口,然后把数据报传递给相应的数据链路,IP可能在把数据报传递给数据链路之前将其分片。
  • 每个数据链路都有一个输出队列,如果该队列已满,那么新到的分组将被丢弃,并沿协议栈向上返回一个错误:从数据链路到IP,再从IP到TCP。TCP将注意到这个错误,并在以后某个时刻重传相应的分节。应用进程并不知道这种暂时的情况。

0 1
原创粉丝点击