计算机网络(1)- TCP

  1. TCP的全称是传输控制协议(Transmission Control Protocol)[RFC 793]
  2. TCP提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP不提供广播或多播服务。由于TCP要提供可靠的、面向连接的服务,因此不可避免地增加了许多的开销,如确认、流量控制、计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多的处理机资源。
  3. 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。

猜你喜欢

转载自www.cnblogs.com/BigJunOba/p/9728796.html