详解TCP连接的建立

TCP报文段首部包含源端口和目的端口,用于标识连接;序列号和确认号确保数据有序无丢失传输;控制位如URG、ACK、PSH等指示紧急数据、确认接收和推送数据。三次握手包括客户端发送SYN请求,服务器回应SYN+ACK,客户端再次确认建立连接。四次挥手用于连接释放。同时打开的连接可能产生碰撞,通过额外的确认避免资源浪费。
摘要由CSDN通过智能技术生成
  1. TCP首部格式

    TCP报文段首部的前20个字节是固定的,后面有4N字节是根据需要而增加的选项,因此TCP报文段的最小长度为20字节。
    首部固定部分的各字段的意义如下:
    1.源端口和目的端口:加上IP首部的源IP地址和目的IP地址,确定唯一的一个TCP连接。另外通过目的端口来决定TCP将数据报交付于哪个应用程序,从而实现TCP的分用功能。
    2.序列号:占4个字节,序列号的范围为[0到2的32次幂],由于TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,首部中的序列号字段则是指本报文段所发送的数据的第一个字节的序列号,另外序列号是循环使用的,当序列号增加到最大值时,下一个序列号就又回到了0。
    3.确认号:当ACK标志位为1时有效,表示期望收到的下一个报文段的第一个数据字节的序列号。确认号为N,则表示序列号N-1为止的所有数据字节都已经被正确地收到了。
    4.首部长度:TCP报文段的首部长度,它指出TCP报文段的数据部分的起始位置与TCP报文段的起始位置的距离。头部长度占4个字节,但它的单位是4字节,因此首部长度的最大值为15×4=60字节,这就意味着选项的长度不超过40字节。
    5.保留位:必须为0。
    6.下面的6个控制位说明报文段的性质:
    (1)URG(URGent):与首部中的紧急指针字段配合使用。当URG为1时,表明紧急指针字段有效,发送应用进程告诉发送方的TCP有紧急数据要传送,于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而其后面仍是普通数据。
    (2)ACK(ACKnowledgement):仅当ACK=1时确认号字段才有效,当ACK=0时,确认号无效。TCP规定:在连接建立后所有的传送报文段置1。
    (3)PSH(PUSH):如果发送的报文段中PSH为1,则接收方接收到该报文段后,直接将其交付给应用程序,而不再等待缓存都填满后再向上交互。
    (4)RST(RESET):复位标志,RST为1时,表明TCP连接中出现严重差错,必须释放连接,然后重新建立运输连接。
    (5)SYN(SYNchronization):同步序号,用来发起一个连接。当SYN=1而ACK=0时,表明这是一个连接请求报文段,若对方同意建立连接,则应在响应的报文段中使SYN=1和ACK=1。
    (6)FIN(FINish):用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放连接。
    7.窗口:接收方让发送方下次发送报文段时设置的发送窗口大小。
    8.校验和:校验的字段范围包括首部和数据这两部分。
    9.紧急指针:当URG=1时才有效,它指出本报文段中的紧急数据的字节数。PS:即使窗口为0时,也可发送紧急数据。
    10.选项与填充:选项应为4字节的整数倍,否则用0填充。最常见的可选字段是最长报文大小MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段中指明这个选项。它指明本端所能接收的最大长度的报文段。该选项如果不设置,默认为536(20+20+536=576的IP数据报),其中IP首部和TCP首部各20个字节,而internet上标准的MTU(Maximum Transmission Unit最大传输单元)最小为576B。

  2. TCP连接的建立

    服务端的TCP进程先创建传输控制块TCB,准备接收客户端进程的连接请求,然后服务端进程处于LISTEN,等待客户端的连接请求,如有,则作出响应。
    1.客户端的TCP进程也首先创建传输控制模块TCB(Transmission control module),然后向服务端发出连接请求报文段,该报文段首部中SYN=1,ACK=0,同时选择一个初始序号seq=i。TCP规定:SYN=1的报文段不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态,这时TCP的第一次握手。
    2.服务端收到客户端发来的请求报文后,如果同意建立连接,则向客户端发送确认。确认报文中的SYN=1,确认号ack=i+1,同时为自己选择一个初始序号seq=j。同样该报文段也是SYN=1的报文段,不能携带数据,但同样要消耗掉一个序号。这时,TCP服务端进入SYN-RCVD(received),这是TCP连接的第二次握手。
    3.TCP客户端进程收到服务端进程的确认后,还要向服务端给出确认。确认报文段的ACK=1,确认号ack=j+1,而自己的序号为seq=i+1。TCP的标准规定,ACK报文段可以携带数据,但如果不携带数据则不消耗序号。因此,如果不携带数据,则下一个报文段的序号仍为seq=i+1。这时,TCP连接已经建立,客户端进入ESTABLISHED(已建立连接)状态。这是TCP连接的第三次握手,可以看出第三次握手客户端已经可以发送携带数据的报文段了。
    当服务端收到确认后,也进入已建立连接状态。

  3. 双方同时主动连接的TCP连接建立过程
    正常情况下,传输连接都是由一方主动发起的,但也有可能双方同时主动发起连接,此时就会发生连接碰撞,最终只有一个连接能够建立起来。因为所有连接都是由它们的端点进行标识的。如果第一个连接请求建立起一个由套接字(x,y)标识的连接,而第二个连接也建立了这样一个连接,那么在TCP实体内部只有一个套接字表项。
    当出现同时发出连接请求时,则两端几乎在同时发送一个SYN字段置1的数据段,并进入SYN_SENT状态。当每一端收到SYN数据段时,状态变为SYN_RCVD,同时它们都再发送SYN字段置1,ACK字段置1的数据段,对收到的SYN数据段进行确认。当双方都收到对方的SYN+ACK数据段后,便都进入ESTABLISHED状态。但最终建立的是一个TCP连接。

    PS:一个双方同时打开的传输连接需要交换4段数据段,比正常的传输连接建立所进行的3次握手多交换1个数据段。此时没有任何一端称为客户或服务器,因为每一端既是客户又是服务器。

  4. 为什么一定要进行三次握手呢?
    1.前2次的握手很显然是必须的,主要是最后一次,这主要是为了防止已失效的请求报文段突然又传送到了服务端而产生连接的误判。
    2.考虑如下的情况:客户端发送了一个连接请求报文段到服务端,但是在某些网络节点上长时间滞留了,而后客户端又超时重发了一个连接请求报文段到该服务端,而后正常建立连接,数据传输完毕,并释放了连接。如果这时候第一次发送的请求延迟了一段时间后,又到了服务端,很显然,这本是一个早已失效的报文段,但是服务端收到后会误以为客户端又发出了一次连接请求,于是向客户端发出确认报文段,并同意建立连接。假设不采用3次握手,这时只要发送了确认,新的连接就建立了,但由于客户端并没有发出建立连接的请求,因此不会理会服务端的确认,也不会向服务端发送数据,而服务端却认为新的连接已经建立了,并在一直等待客户端发送数据,这样服务端就会一直等待下去,直到超出保活计数器的设定值,而将客户端判定为出了问题,才会关闭这个连接,这样就浪费了很多服务器的资源。而如果采用三次握手,客户端就不会向服务端发出确认,服务端由于收不到确认,就知道客户端没有要求建立连接,从而不建立连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值