不抓包,如何学得了 TCP

Wireshark

本机ip: 192.168.0.72html

访问地址: [http://www.cnblogs.com/tankxiao]()服务器

wireshark01

记录378,419,427就对应着著名的TCP三次握手网络

数据帧格式以下学习

wireshark02

三次握手流程图spa

w03

SYN:创建链接计算机网络

FIN:关闭链接server

ACK:响应htm

PSH:数据传输blog

RST:链接重制ip

A->B:在吗?听的到吗?

B->A:在啊?你听获得吗?(告诉A,经过B的回复来确认,A->B通讯正常)

A->B:听的见(告诉B,经过A的回复来确认,B->A通讯正常)

第一次握手

客户端向服务端创建链接的信号 Syn = 1,seq 为随机数

图中 Sequence number: 0 (relative sequence number),反映的是相对seq

真实的 seq 在图中下部分,用16进制 "532d0c99"表示,转换成10进制为 "1395461273"

w04

第二次握手

服务端向客户端发送响应 Ack = seq(来自客户端,1395461273) + 1,Syn = 1,seq 为随机数

图中 Acknowledgment number: 1 (relative ack number),反映的是相对Ack

真实的 ack 在图中下部分,用16进制"532d0c9a"表示,转换成10进制为 "1395461274"

同理 seq "96fb78d2" 的10进制为 "2533062866"

w05

第三次握手

客户端向服务端发送响应 Ack = seq (来自服务端,2533062866) + 1,seq 为随机数

图中 Ack 的16进制为"96fb78d3",转换成10进制为"2533062867"

图中 seq 的16进制为"532d0c9a",转换成10进制为"1395461274"

w06

至此之后,客户端就能够愉快地和服务端通讯了

为何是三次握手

“已失效的链接请求报文段”的产生在这样一种状况下:client发出的第一个链接请求报文段并无丢失,而是在某个网络结点长时间的滞留了,以至延误到链接释放之后的某个时间才到达server。原本这是一个早已失效的报文段。但server收到此失效的链接请求报文段后,就误认为是client再次发出的一个新的链接请求。因而就向client发出确认报文段,赞成创建链接。假设不采用“三次握手”,那么只要server发出确认,新的链接就创建了。因为如今client并无发出创建链接的请求,所以不会理睬server的确认,也不会向server发送数据。但server却觉得新的运输链接已经创建,并一直等待client发来数据。这样,server的不少资源就白白浪费掉了。采用“三次握手”的办法能够防止上述现象发生。例如刚才那种状况,client不会向server的确认发出确认。server因为收不到确认,就知道client并无要求创建链接。”

摘自谢希仁著《计算机网络》

传输过程

TCP维持数据不丢失的关键在于Seq和Ack

w08

w09

在18.443018时,客户端向服务端发送数据包P1,内容是发送http请求,Seq = 1,Len = 1083,命名为数据包P1

在18.469641时,服务端告诉客户端数据包P1已经收到, Ack = 数据包P1的Seq + 数据包P1的Len

在18.495616时,服务端向客户端发送数据包P2,内容是html文档,Seq = 1, Len = 1452

在18.495617时,服务端向客户端发送数据包P3,内容还是html文档,Seq = 1453,Len = 133

在18.495680时,客户端告诉服务端数据包P3已经收到,Ack = 数据包P3的Seq + 数据包P3的Len

TCP提供的确认机制,能够在通讯过程当中能够不对每个TCP数据包发出单独的确认包(Delayed ACK机制),而是在传送数据时,顺便把确认信息传出, 这样能够大大提升网络的利用率和传输效率。同时,TCP的确认机制,也能够一次确认多个数据报,例如,接收方收到了201,301,401的数据报,则只 须要对401的数据包进行确认便可,对401的数据包的确认也意味着401以前的全部数据包都已经确认,这样也能够提升系统的效率。

在18.496954-18.496961期间,服务端发送了5个数据包,其中最后一个数据包是响应头,"HTTP/1.1 200 OK..."

在18.497018-18.499389期间,客户端对发来的数据包进行确认

Seq 与 Ack 的关系

w11

w10

发送数据包,数据的序号Seq和数据的长度Len

确认包,Ack = 收到的最后的数据包的序号Seq+Len,

同时由于做为确认包,在服务端与客户端交换数据的过程当中,没有向服务端发送数据,因此 Seq 不变

在某种程度上能够这样理解Seq和Ack,在发送这个包以前,我已经向对方发送的数据量Seq,我已经接受到的数据量Ack

四次挥手

w12

w13

为何创建链接协议是三次握手,而关闭链接是四次握手

这是由于服务端的LISTEN状态下的SOCKET当收到SYN报文的链接请求后,它能够把ACK和SYN(ACK起应答做用,而SYN起同步做用)放在一个报文里来发送。但关闭链接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你全部的数据都所有发送给对方了,因此你可能未必会立刻会关闭SOCKET,也即你可能还须要发送一些数据给对方以后,再发送FIN报文给对方来表示你赞成如今能够关闭链接了,因此它这里的ACK报文和FIN报文多数状况下都是分开发送的。

因为TCP链接是全双工的,所以每一个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的链接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP链接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另外一方执行被动关闭。

(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。

(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN同样,一个FIN将占用一个序号。

(3)服务器B关闭与客户端A的链接,发送一个FIN给客户端A。

(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。

A->B:我对你已经没话说了

B->A:我知道你对我没话说了

B->A:我对你也没话说了

A->B:我知道你对我也没话说了

TCP和UDP的区别

  1. TCP是基于链接的,而UDP是无链接的
  2. TCP的数据传输是点对点的,而UDP支持一对一,一对多,多对一和多对多的交互通讯
  3. 对系统资源的要求(TCP较多,UDP少)
  4. UDP程序结构较简单
  5. TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证
  6. TCP首部开销20字节,UDP的首部开销小,只有8个字节

参考资料

相关文章
相关标签/搜索