计算机网络- TCP
Posted bigjunoba
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机网络- TCP相关的知识,希望对你有一定的参考价值。
- TCP的全称是传输控制协议(Transmission Control Protocol)[RFC 793]
- TCP提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP不提供广播或多播服务。由于TCP要提供可靠的、面向连接的服务,因此不可避免地增加了许多的开销,如确认、流量控制、计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多的处理机资源。
- TCP最主要的特点:
- TCP是面向连接的传输层协议。即应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。
- 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的。
- TCP提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复并且按序到达。
- TCP提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。在发送时,应用程序在吧数据传送给TCP的缓存后,就可以做自己的事,而TCP在合适的时候把数据发送出去。在接收时,TCP把收到的数据放入缓存,上层的应用进程在合适的时候读取缓存中的数据。
- 面向字节流。TCP中的“流(stream)”指的是流入到进程或从进程流出的字节序列。“面向字节流”的含义是,虽然应用程序和TCP的交互式是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串无结构的字节流。TCP并不知道所传送的字节流的含义。
4.TCP的连接
TCP把连接作为最基本的抽象。TCP连接的端点叫做套接字或插口。
每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定。即:
TCP连接 ::= {socket1,socket2} = {(IP1:port1),(IP2:port2)}
5.TCP的运输连接管理
(1)TCP的连接建立
假设主机A运行的TCP客户程序,而B运行的是TCP服务器程序。最初两端的TCP进程都处于CLOSED(关闭)状态。A主动打开连接,而B被动打开连接。
连接过程:
初始状态:B的TCP服务器进程先创建传输控制块TCB,准备接受客户进程的连接请求。然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。如有,即作出响应
- 在打算建立TCP连接时,向B发出连接请求报文段,这是首部中的同步位SYN = 1,同时选择一个初始序号seq = x。这时TCP客户进程进入SYN-SENT(同步已发送)状态。
- B收到连接请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把SYN位和ACK位都置1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。这是TCP服务器进程进入SYN-RCVD(同步收到)状态。
- TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1。这时,TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。
连接建立后的状态:当B收到A的确认后也进入ESTABLISHED(已建立连接)状态。
问题1:为什么A最后还要发送一次确认呢?
是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。
解释:假设A发出连接请求,但因连接请求报文丢失而未收到确认。于是,A再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。A共发送了两个连接 请求报文段,其中第一个丢失,第二个到达了B,此时没有“已失效的连接请求报文段”。假设A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延 误到连接释放之后的某个时间才到达B。本来这是一个早已失效的报文段,但B收到此失效的连接请求报文段后,就误以为是A又发出一次新的连接请求。于是就向A发出确认报文 段,同意建立连接。假如不采用三次握手,即没有最后一次连接确认,那么只要B向A发出同意连接请求,新的连接就建立了。然而由于此时A并没有发出建立连接的请求,因此不会 理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立了,并一直等待A发来的数据。B的许多资源就这样白白浪费了。
(2)TCP的连接释放
TCP连接释放的过程:
初始过程:数据传输结束后,通信的双方都可释放连接。现在A和B都处于ESTABLISHED状态。A的应用进程现象器TCP发出连接释放报文段,并停止发送数据,主动关闭TCP连接。
- A把连接释放报文段首部的终止控制位FIN=1,其序号seq=u,u等于前面A已传送过的数据的最后一个字节的序号加1。这是A进入FIN-WAIT1(终止等待1)状态,等待B的确认。
- B收到连接释放报文段后即发出确认,确认号是ack=u+1,其序号seq=v,v等于B前面已传送过的数据的最后一个字节的序号加1。然后B进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭状态,即A已经没有数据要发送了,但B若发送数据,A仍要接收,也就是说,从B到A这个方向的连接并未变比,这个状态可能会持续一段时间。A收到来自B的确认后,就进入FIN-WAIT-2(终止等待-2状态),等待B发出的连接释放报文段。
- 若B已经没有要向A发送的数据了,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN=1。先假定B的序号为w(在半关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号ack = u + 1.这时B就进入LAST-ACK(最后确认)状态,等待A确认。
- A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中把ACK = 1,确认号ack = w + 1,而自己的序号是seq = u + 1。然后进入到TIME-WAIT(时间等待状态),必须经过时间等待计时器设置的时间2MSL(MSL叫做最长报文段寿命)后,A才进入到CLOSED状态。
连接释放后的状态:B收到A的报文后也进入到CLOSED状态。
5.使用tcpdump分析tcp连接过程
场景:同一个局域网下,192.168.131.138上运行着apache2服务器(默认端口为80),同时apache2服务器上有大小为64KB的文件,名称为file64KB。
192.168.132.132上使用脚本,不停地运行wget http://192.168.131.138/file64KB去不停地下载192.168.131.138上的文件。
在192.168.131.132上运行tcpdump tcp -i ens33 -n命令,抓包。抓包结果如下:
1 10:09:11.163215 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [S], seq 3124300130, win 29200, options [mss 1460,sackOK,TS val 1666537180 ecr 0,nop,wscale 7], length 0 2 10:09:11.163355 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [S.], seq 2508684482, ack 3124300131, win 28960, options [mss 1460,sackOK,TS val 2620718342 ecr 1666537180,nop,wscale 7], length 0 3 10:09:11.163390 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 1666537180 ecr 2620718342], length 0 4 10:09:11.163458 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [P.], seq 1:152, ack 1, win 229, options [nop,nop,TS val 1666537180 ecr 2620718342], length 151: HTTP: GET /file_64KB HTTP/1.1 5 10:09:11.163569 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], ack 152, win 235, options [nop,nop,TS val 2620718342 ecr 1666537180], length 0 6 10:09:11.163787 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 1:7241, ack 152, win 235, options [nop,nop,TS val 2620718342 ecr 1666537180], length 7240: HTTP: HTTP/1.1 200 OK 7 10:09:11.163813 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 7241, win 342, options [nop,nop,TS val 1666537180 ecr 2620718342], length 0 8 10:09:11.163848 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 7241:14481, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537180], length 7240: HTTP 9 10:09:11.163862 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 14481, win 455, options [nop,nop,TS val 1666537180 ecr 2620718343], length 0 10 10:09:11.163969 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 14481:24617, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537180], length 10136: HTTP 11 10:09:11.163975 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 24617, win 613, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 12 10:09:11.164011 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [P.], seq 24617:28961, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537180], length 4344: HTTP 13 10:09:11.164014 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 28961, win 681, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 14 10:09:11.164038 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 28961:37649, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537180], length 8688: HTTP 15 10:09:11.164043 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 37649, win 817, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 16 10:09:11.164062 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [P.], seq 37649:43441, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 5792: HTTP 17 10:09:11.164065 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 43441, win 907, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 18 10:09:11.164098 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 43441:57921, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 14480: HTTP 19 10:09:11.164112 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 57921, win 1134, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 20 10:09:11.164149 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 57921:62265, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 4344: HTTP 21 10:09:11.164154 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 62265, win 1201, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 22 10:09:11.164180 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [P.], seq 62265:65801, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 3536: HTTP 23 10:09:11.164183 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 65801, win 1236, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 24 10:09:11.164485 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [F.], seq 152, ack 65801, win 1257, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 25 10:09:11.164863 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [F.], seq 65801, ack 153, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 0 26 10:09:11.164882 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 65802, win 1257, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 27 28 29 10:09:11.168172 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [S], seq 2780780137, win 29200, options [mss 1460,sackOK,TS val 1666537185 ecr 0,nop,wscale 7], length 0 30 10:09:11.168343 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [S.], seq 825503549, ack 2780780138, win 28960, options [mss 1460,sackOK,TS val 2620718347 ecr 1666537185,nop,wscale 7], length 0 31 10:09:11.168377 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 1666537185 ecr 2620718347], length 0 32 10:09:11.168507 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [P.], seq 1:152, ack 1, win 229, options [nop,nop,TS val 1666537185 ecr 2620718347], length 151: HTTP: GET /file_64KB HTTP/1.1 33 10:09:11.168728 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [.], ack 152, win 235, options [nop,nop,TS val 2620718347 ecr 1666537185], length 0 34 10:09:11.168964 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [.], seq 1:14481, ack 152, win 235, options [nop,nop,TS val 2620718348 ecr 1666537185], length 14480: HTTP: HTTP/1.1 200 OK 35 10:09:11.168992 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [.], ack 14481, win 455, options [nop,nop,TS val 1666537186 ecr 2620718348], length 0 36 10:09:11.169150 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [P.], seq 14481:28961, ack 152, win 235, options [nop,nop,TS val 2620718348 ecr 1666537186], length 14480: HTTP 37 10:09:11.169174 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [.], ack 28961, win 681, options [nop,nop,TS val 1666537186 ecr 2620718348], length 0 38 10:09:11.169176 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [.], seq 28961:37649, ack 152, win 235, options [nop,nop,TS val 2620718348 ecr 1666537186], length 8688: HTTP 39 10:09:11.169180 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [.], ack 37649, win 817, options [nop,nop,TS val 1666537186 ecr 2620718348], length 0 40 10:09:11.169278 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [P.], seq 37649:43441, ack 152, win 235, options [nop,nop,TS val 2620718348 ecr 1666537186], length 5792: HTTP 41 10:09:11.169294 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [.], ack 43441, win 907, options [nop,nop,TS val 1666537186 ecr 2620718348], length 0 42 10:09:11.169308 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [.], seq 43441:56473, ack 152, win 235, options [nop,nop,TS val 2620718348 ecr 1666537186], length 13032: HTTP 43 10:09:11.169310 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [.], ack 56473, win 1111, options [nop,nop,TS val 1666537186 ecr 2620718348], length 0 44 10:09:11.169375 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [P.], seq 56473:65801, ack 152, win 235, options [nop,nop,TS val 2620718348 ecr 1666537186], length 9328: HTTP 45 10:09:11.169414 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [.], ack 65801, win 1257, options [nop,nop,TS val 1666537186 ecr 2620718348], length 0 46 10:09:11.169713 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [F.], seq 152, ack 65801, win 1257, options [nop,nop,TS val 1666537186 ecr 2620718348], length 0 47 10:09:11.170218 IP 192.168.131.138.80 > 192.168.131.132.37586: Flags [F.], seq 65801, ack 153, win 235, options [nop,nop,TS val 2620718349 ecr 1666537186], length 0 48 10:09:11.170243 IP 192.168.131.132.37586 > 192.168.131.138.80: Flags [.], ack 65802, win 1257, options [nop,nop,TS val 1666537187 ecr 2620718349], length 0
背景知识:关于Flags后面紧跟的中括号里面的内容所表达的意思:
- S = SYN,表示发起连接标识
- P = PUSH,表示传送数据标识
- F = FIN,表示关闭连接标识
- . + ack 表示确认包
上面的结果显示了两次使用http协议下载文件的过程(从每一行的最后的字段都可以看出规律)。
包括三个过程:TCP连接建立--HTTP协议下载文件--TCP连接关闭。下面逐一分析这三个过程:
把客户端192.168.131.132记为A,服务端192.168.131.138记为B,则有
(1)TCP三次握手连接建立过程:
1 10:09:11.163215 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [S], seq 3124300130, win 29200, options [mss 1460,sackOK,TS val 1666537180 ecr 0,nop,wscale 7], length 0 2 10:09:11.163355 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [S.], seq 2508684482, ack 3124300131, win 28960, options [mss 1460,sackOK,TS val 2620718342 ecr 1666537180,nop,wscale 7], length 0 3 10:09:11.163390 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 1666537180 ecr 2620718342], length 0
第一步:A向B发送连接请求[S],seq = 3124300130
第二步:B向A发送同意连接[S.],ack = 3124300130 + 1 = 3124300131, seq = 2508684482
第三次:A向B发送确认连接[.],这里是由于tcpdump采用了相对量的表示方法,ack = 1的意思是ack的值等于第二步中的 seq 值加上1,实际上是 2508684482 + 1 = 2508684483
(2)HTTP协议部分(先挖坑,后面学习完之后再来分析HTTP过程)
第一行:HTTP: GET /file_64KB HTTP/1.1
1 4 10:09:11.163458 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [P.], seq 1:152, ack 1, win 229, options [nop,nop,TS val 1666537180 ecr 2620718342], length 151: HTTP: GET /file_64KB HTTP/1.1 2 5 10:09:11.163569 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], ack 152, win 235, options [nop,nop,TS val 2620718342 ecr 1666537180], length 0 3 6 10:09:11.163787 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 1:7241, ack 152, win 235, options [nop,nop,TS val 2620718342 ecr 1666537180], length 7240: HTTP: HTTP/1.1 200 OK 4 7 10:09:11.163813 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 7241, win 342, options [nop,nop,TS val 1666537180 ecr 2620718342], length 0 5 8 10:09:11.163848 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 7241:14481, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537180], length 7240: HTTP 6 9 10:09:11.163862 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 14481, win 455, options [nop,nop,TS val 1666537180 ecr 2620718343], length 0 7 10 10:09:11.163969 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 14481:24617, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537180], length 10136: HTTP 8 11 10:09:11.163975 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 24617, win 613, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 9 12 10:09:11.164011 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [P.], seq 24617:28961, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537180], length 4344: HTTP 10 13 10:09:11.164014 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 28961, win 681, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 11 14 10:09:11.164038 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 28961:37649, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537180], length 8688: HTTP 12 15 10:09:11.164043 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 37649, win 817, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 13 16 10:09:11.164062 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [P.], seq 37649:43441, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 5792: HTTP 14 17 10:09:11.164065 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 43441, win 907, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 15 18 10:09:11.164098 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 43441:57921, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 14480: HTTP 16 19 10:09:11.164112 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 57921, win 1134, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 17 20 10:09:11.164149 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [.], seq 57921:62265, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 4344: HTTP 18 21 10:09:11.164154 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 62265, win 1201, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 19 22 10:09:11.164180 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [P.], seq 62265:65801, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 3536: HTTP
(3)TCP连接释放过程
1 22 10:09:11.164180 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [P.], seq 62265:65801, ack 152, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 3536: HTTP 2 23 10:09:11.164183 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 65801, win 1236, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0
3 24 10:09:11.164485 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [F.], seq 152, ack 65801, win 1257, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0 4 25 10:09:11.164863 IP 192.168.131.138.80 > 192.168.131.132.37584: Flags [F.], seq 65801, ack 153, win 235, options [nop,nop,TS val 2620718343 ecr 1666537181], length 0 5 26 10:09:11.164882 IP 192.168.131.132.37584 > 192.168.131.138.80: Flags [.], ack 65802, win 1257, options [nop,nop,TS val 1666537181 ecr 2620718343], length 0
第一步:A → B :seq = u = 152,
第二步:B → A :seq = w = 65801,ack = u + 1 = 153。
第三步:A → B :ack = w + 1 = 65802
只有三步的原因是:在TCP释放连接过程的第一个过程之后,由于第二个过程和第三个过程之间,B没有数据发送给A,因此这里将两个过程一起发送给A。
以上是关于计算机网络- TCP的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段14——Vue的axios网络请求封装