怎么判断tcp重组完成_《UNIX网络编程》笔记之TCP协议的连接和终止

TCP/IP

TCP/IP是分层的通讯协议,应用程序数据的发送是沿着协议栈从上往下依次传递,每层协议都在上层数据的基础上加上自己的头部信息,以实现该层的功能。比如,TCP头部信息和TCP内核发送(接收)缓冲区数据,经过封装后成为TCP报文段。

  • 应用层在用户空间实现,负责处理应用程序的业务逻辑,比如文件传输、网络管理等。
  • 传输层为应用进程封装了一个端到端的连接,负责数据的收发、链路的超时重连等。
  • 网络层提供数据包的路径选择和转发。一般情况下通信的两台主机是由中间多个网络节点连接,网络层封装了网络拓扑连接的细节,使得传输层和应用层看来通信的双方是直连的。
  • 数据链路层实现了网卡接口的驱动程序,处理数据在物理硬件上的传输。

IP协议是网络层的核心,IP头部信息包含通信的源端和目的端的IP地址。

使用逐跳的方式确定通信路径,根据IP数据包的目的IP地址来投递,如果数据包不能直接发送给目标主机,则寻找合适的下一跳路由器并通过它将数据包转发出去,直至到达目标主机。

当IP数据包的长度超过帧的MTU时,会被分片传输,分片可能发生在发送端或中转的路由器上,也可能在传输过程中被多次分片,最终由接收端的IP模块完成重组。

IP协议为上层的TCP协议提供无状态、无连接、不可靠的服务。
  • 无状态是指IP通信的双方不同步传输数据的状态信息。IP数据报的发送、传输、接收都是相互独立的,可能会出现乱序和重复的数据报,接收端检测到IP数据报是分片则执行重组,然后将完整IP数据包交给上层协议。
  • 无连接是指IP通信的双方都不持久保存对方的任何信息,每次发送数据都要指明对方的IP地址。
  • 不可靠是指不能保证IP数据报准确到达接收端,只是尽最大努力。
TCP是一种可靠的传输控制协议,核心思想是要保证可靠传输。

面向连接:TCP提供客户端与服务器之间的连接,客户端先与某个服务建立一个连接,再通过该连接与服务器交换数据,然后终止连接。

传输可靠性:当TCP向另一端发送数据时,要求对端返回一个确认(ACK);如果没有收到确认,TCP就自动重传,在数次重传失败后才放弃。

数据分节传输:TCP对所发送数据的每个字节关联一个序列号进行排序。如果分节数据非顺序到达,接收端TCP将根据序列号重新排序,再把结果数据传递给应用;也可以根据序列号判断数据是否重复(如果发送端认为一个分节已丢失而重传,但没有真正丢失,只是网络过于拥挤),重复则丢弃。

流量控制:TCP通过“通告窗口”告知对端一次能够接收多少字节的数据。接收端可以指定接收缓冲区的空间,从而确保对端发送的数据不会使接收缓冲区溢出。窗口大小时刻动态变化,当窗口大小为0时,表示接收缓冲区已满,需要等待应用从缓冲区读取数据时才能继续接收。

MSS分节最大值:向对端通告在每个分节中可发送的最大字节数,即TCP提交给IP层最大字节数,从而试图避免分片。MSS在IPv4中通常被设置成1460,MSS = 1500(MTU) - 20(IP Header) - 20(TCP Header)。MTU即物理接口(数据链路层)一次传输数据的最大单元,默认MTU=1500。

全双工:建立TCP连接后,在任何时刻在进出两个方向上同时发送和接收数据。

TCP连接的建立

服务器准备好接受外部的连接(被动连接),应用通过调用socket、bind、listen这3个函数完成。

TCP的三路握手

第一步,客户端调用connect发起主动连接,导致客户端TCP发送一个SYN(同步)分节,它会告诉服务器即将建立的连接中要发送的数据的初始序列号。状态为SYN_SENT。

第二步,服务器必须确认(ACK)客户端的SYN,同时自己也发送一个SYN分节,它含有服务器将在连接中要发送的数据的初始序列号。服务器对客户端的SYN确认是伴随其应答发送的SYN,称为捎带。

第三步,客户端接收到一个带ACK的SYN,它发送一个ACK以确认服务器的SYN,此时状态为established(已建立)。

57b3bfd7cf8a0875366d6e2e5dc30a65.png

客户端和服务器程序都是从socket调用开始,打开一个网络套接字。服务器调用bind、listen、accept,客户端调用connect。

TCP连接终止

TCP建立一个连接需要3个分节,终止一个连接则需要4个分节。

1、调用close执行主动关闭,该端的TCP发送一个FIN分节,表示数据发送完毕。

2、接收到这个FIN的对端执行被动关闭。FIN也相当于一个文件结束符(end-of-file),意味着连接上无数据可接收。接收端TCP确认FIN。

3、过了一会,接收到这个FIN(文件结束符)的应用进程调用close关闭它的套接字,导致它的TCP也发送一个FIN。

4、主动关闭端收到FIN并发送确认(ACK)。

b9b115a9b2cf9d868b96cf8230594d7f.png

客户端和服务器端都可以执行主动关闭(通常情况是客户端执行),不过当应用进程退出或意外终止时,已打开的套接字描述符会被关闭,也会导致TCP连接发出一个FIN。

半关闭状态,(步骤2和步骤3TCP的全双工允许两个方向上的连接被独立关闭,发送结束报文(FIN)给对端表示数据已发送完,但允许继续接收对端的数据,直到对端也发送结束报文以关闭连接。

TIME_WAIT状态,客户端在收到服务器的结束报文后,不是直接进入close状态,而是转移到TIME_WAIT状态,客户端要等待一段2MSL(报文的最大生存时间)的时间,才关闭连接。

TCP输出

Socket将TCP实现细节封装成API,虽然Socket不等于TCP,但TCP的缓冲区和Socket缓冲区应该是指向相同内存空间。

TCP Socket有一个发送缓冲区,可以通过SO_SNDBUF选项更改。当应用进程调用write时,内核将应用进程的缓冲区全部数据复制到TCP Socket的发送缓冲区。

当TCP的发送缓冲区容不下应用进程的所有数据,write调用不会返回,应用进程阻塞直到数据都被复制到TCP发送缓冲区。write调用的返回仅仅表示数据成功写到TCP发送缓冲区,并不表示数据成功发送到对端TCP。

TCP输入

TCP Socket的输入操作通常包含两个步骤:

第一,等待数据从网络中达到。分节数据到达后被复制到内核缓冲区。

第二,将数据从内核缓冲区复制到应用进程缓冲区。

TCP socket套接字选项

保持存活SO_KEEPALIVE

如果客户端进程崩溃,它的TCP会自动发送一个FIN,服务器是可以检测到。

如果客户端主机崩溃或网络不可达,服务器是不知道的,只会继续等待数据达到。

keep-alive用于探测这种半开连接并终止它们。

如建立的socket在2小时内没有数据交换,TCP会自动向对端发送一个保持存活探测分节,可能会有3种情况:

1、对端响应ACK,表示连接正常,如2小时后仍无数据交换则继续发送探测;

2、对端响应RST,表示对端已崩溃且已重新启动,socket被关闭。

3、对端没有任何响应,则继续发送8个探测分节。如根本没有响应则等处理错误被设置为ETIMEOUT,socket被关闭。或收到其他的探测错误。

SO_LINGER

对TCP连接调用close函数,默认情况下是立即返回,如果socket的发送缓冲区中有数据,系统将试着把数据发送出去。

当l_linger为0,将丢弃socket发送缓冲区的任何数据,并发送一个RET给对端,通常没有终止连接的4个分节。

当l_linger为非0,内核将延时一段时间关闭socket,如果socket的发送缓冲区有数据,则应用进程将投入睡眠,直到所有数据都已发送完且被对方确认或延滞时间到。否则返回错误并丢弃数据。

SO_RCVBUF和SO_SNDBUF

每个套接字都有一个发送缓冲区和一个接收缓冲区。对于双向数据传输,分别指接收端和发送端的收发两个套接字缓冲区的大小。

设置TCP套接字接收缓冲区的大小的顺序很重要,因为TCP的通告窗口大小是在建立连接时使用SYN分节与对端互换得到,对于客户端,SO_RCVBUG必须再调用connect之前设置,对于服务器,必须在调用listen之前设置。

TCP套接字缓冲区的大小至少是MSS值的4倍,默认值为8192字节,默认的MSS值为1460。是依据TCP快速恢复算法的工作机制,TCP发送端使用3个重复确认来检测某个分节是否丢失,发现某个分节丢失后,接收端将给新收到的每个分节发送一个重复的确认。如果窗口大小不足以存放4个分节,就没法连发3个重复的确认。

SO_RCVLOWAT和SO_SNDLOWAT

每个套接字都有一个接收低水位标记和一个发送低水位标记。

接收低水位标记是让read返回接收缓冲区的最小数据值,即大于此值read就返回。

发送低水位标记是让write对发送缓冲区可写空间的最小数据值,即大于此值write可写。

SO_RCVTIMEO和SO_SNDTIMEO

设置套接字的接收和发送超时值,会影响read系列和write系列的函数。默认是禁止超时。

IP_TTL

TTL是IP数据包在计算机网络中可以转发的最大跳数,避免IP包在网络中无线循环和收发。TTL由套接字的发送端设置,默认值为64,最大值255。

P数据包从发送端到接收端的整个转发路径,每经过一个路由器就把TTL的值减1再转发出去。如果IP数据包在到达接收端之前,TTL减少为0时路由器丢弃数据包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值