TCP报文段首部格式:
(1).源端口和目的端口 :各占两个字节,分别写入源端口号和目的端号。
(2).序号:占4个字节。序号范围为[0-2^32-1]。序号增加到2的32次方-1时,下一个序号返回到0;传送的字节流中每一个字节按序号排列。整个要传送的字节流的起始序号必须在连接时设置。例如:一报文段的序号字段值是301,最后一个字节序号是400,显然,下一个报文段的第一个字节序号是401。
(3).确认号: 占4个字节,是期望收到对方下一个报文段的第一个字节的序号。
(4).数据偏移:占4位,它指出TCP报文段的数据的起始处距离TCP报文段的起始处有多远。
(5).保留:占6位,保留为今后使用,但目前为0。
(6)紧急URG:当URG为1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于优先级高的数据),而不要按照原来的顺序传送。例如:已经发送了一个很长的数据在远地的主机上运行,后来发现了一些问题要取消该程序的运行,因此用户从键盘发出中断指令(Contro+1)。如果不使用紧急数据,那么这两个字符将被放在TCP的缓存末尾。只有所有数据被处理完之后这两个字符才被交付到接收方的应用进程。这样就大大地浪费了时间。当URG置1时,发送方就告诉TCP有紧急数据要处理,于是 发送方就把紧急数据插到报文段数据最前面。
(7).确认ACK:仅当ACK置1时,确认号字段才有效。TCP规定,在建立连接后所有传送的报文段都必须把ACK置1.**
(8).推送PSH(PUSH):当两个应用进程进行交互式的通信时,有时一端的应用进程 希望在键入一个命令后就能够收到对方的响应。在这种情况下,TCP就可以使用推送操作,这时,发送方TCP把PSH置1,并且立即创建一个报文段发送出去,接收方TCP收到PSH=1的报文段,就尽快交付接收应用进程,而不用等到整个缓存填满之后再交付。
(9).复位RST:当RST=1时,表明TCP连接中出现严重差错(如主机崩溃),必须立即释放链接,然后再重新建立传输连接。RST置1还可以用来拒绝一个非法的报文段或拒绝打开一个连接。
(10).同步SYN:在建立连接时用来同步序号。当SYN=1,ACK=0,说明这是一个连接请求报文段。若对方同意连接,则在响应报文段中使SYN=1,和ACK=1。
(11).终止FIN:用来释放一个连接。当FIN=1时,说明此报文段的发送方的数据已发送完毕,并要求释放连接。
(12).窗口:指的是发送本报文段的一方的接收窗口,窗口值作为接收方让发送方设置发送窗口的依据。
(13).检验和:占两个字节。检验和检验范围包括首部和数据这两部分。
(14).紧急指针:占2个字节。在URG=1时才有效,指出本报文段中的紧急数据的字节数。紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据处理完时,TCP就告诉应用进程恢复到正常操作。
(15).选项:长度可变,最长可达40个字节。
TCP的建立连接(三次握手):
三次握手过程:
(1).一开始,B的TCP服务器进程先创建TCB传输控制块,准备接受客户端的连接请求。然后服务器就进入LISTEN(监听)状态,等待客户的连接请求。
(2).A的客户进程也是首先创建传输控制块TCB,然后在打算建立TCP连接时,向B发出请求报文段。这时首部位的同步SYN=1,同时选择一个初始序号seq=x.TCP客户端进入SYN-SENT(同步已发送)状态。
(3).B收到连接请求后,如同意建立连接,则向A发送确认。在报文段中把SYN和ACK都置1,确认号ack=x+1,同时也为自己选择一个初始序号seq=y。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。
(4).TCP客户进程收到B的确认后,还好给B发出确认。确认报文段ACK=1,确认号seq=y+1,而自己的序号seq=x+1。A进入ESTABLISHEN(已建立连接)状态。
(5).当B收到A的确认后,也进入ESTABLISHEN状态。
为什么要进行第三次握手?
为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误”,这种情况是:一端(client)A发出去的第一个连接请求报文并没有丢失,而是因为某些未知的原因在某个网络节点上发生滞留,导致延迟到连接释放以后的某个时间才到达另一端(server)B。本来这是一个早已失效的报文段,但是B收到此失效的报文之后,会误认为是A再次发出的一个新的连接请求,于是B端就向A又发出确认报文,表示同意建立连接。如果不采用“三次握手”,那么只要B端发出确认报文就会认为新的连接已经建立了,但是A端并没有发出建立连接的请求,因此不会去向B端发送数据,B端没有收到数据就会一直等待,这样B端就会白白浪费掉很多资源。如果采用“三次握手”的话就不会出现这种情况,B端收到一个过时失效的报文段之后,向A端发出确认,此时A并没有要求建立连接,所以就不会向B端发送确认,这个时候B端也能够知道连接没有建立。
TCP的连接释放(四次挥手):
四次挥手过程:
(1).数据传输结束后,通信的双方都可释放连接。现在A和B都处于ESTABLISHEN状态。如上图,A的应用进程先向其TCP发出释放连接报文段,并停止发送数据,主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN置1,其序号seq=u,它等于前面已传送的数据的最后一个字节序号加1.这时A今日FIN-WAIT-1(终止等待1)状态,等待B的确认。
(2).B收到连接释放报文段后即发出确认,确认后seq=u+1,而将自己的序号seq=v,等于B前面已经发送的数据的最后一个字节的序号加1.然后B就进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时通知高层应用进程,因而A到B的这个方向的连接就关闭了这时的TCP处于半关闭状态。即A没有数据要给B发送了,但B若要发送数据,A仍要接受。也就是说B到A这个方向的连接并没有关闭。
(3).A收到B的确认后,就进入FIN-WAIT2状态,等待B发出连接释放报文段。
(4).若B已经没有数据要给A发送,其应用进程就通知释放连接。这时B发出的连接释放报文段必须使FIN=1.现假定B的的序号为w(在**半关闭状态B可能发送了一些数据),**B还必须确认已发送过的确认号ack=u+1.这时B就进入了LAST-ACK(最后确认)状态,等待A的确认。
(5).A在收到B的连接释放报文后,必须对其发出确认。在报文段中ACK=1,序号seq=u+1,确认号ack=w+1,然后进入TIME-WAIT状态。注意:**现在TCP连接还没有释放必须经过**时间等待计时器设置的时间2MSL**后A才进入CLOSE状态。
为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
第一:为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段很可能丢失,因而B收不到对方已发送的FIN+ACK报文段的确认。B会超时重传FIN+ACK,而A就能在2MSL内重新发送确认,重启2MSL计时器。最后A和B都进入CLOSE状态。
第二:防止已失效的报文段出现在本连接中,A发送完最后一个ACK报文段后,在经过2MSL时间后,可以使本连接持续时间内所产生的所有报文都从网络中消失。这样可使下一个新的连接不会出现旧的连接请求报文段。