成立学校网站建设小组,注册公司流程和资料,高德地图切换国外,怎么做百度采购网站一、TCP报文段结构 1、源端口号和目的端口号都是16位#xff0c;范围从#xff08;1-65535#xff0c;0不可用#xff09; 2、序列号#xff1a;在建立连接时由内核生成的随机数作为其初始值#xff0c;通过 SYN 报文传给接收端主机#xff0c;每发送一次数据#xff0…一、TCP报文段结构 1、源端口号和目的端口号都是16位范围从1-655350不可用 2、序列号在建立连接时由内核生成的随机数作为其初始值通过 SYN 报文传给接收端主机每发送一次数据就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。 3、确认号指下一次「期望」收到的数据的序列号发送端收到接收方发来的 ACK 确认报文以后就可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。 4、控制位用来标识 TCP 报文是什么类型的报文比如是 SYN 报文、数据报文、ACK 报文FIN 报文等。
1、TCP序列号和确认号万能公式
机器发送的 TCP 报文公式如下
公式一序列号 上一次发送的序列号 上一次发送的数据长度 len数据长度。特殊情况如果上一次发送的报文是 SYN 报文或者 FIN 报文则改为上一次发送的序列号 1。公式二确认号 上一次收到的报文中的序列号 上一次收到的报文长度len数据长度。特殊情况如果收到的是 SYN 报文或者 FIN 报文则改为上一次收到的报文中的序列号 1。 SYN 报文长度为1 SYNACK报文长度为1 FIN报文长度为1 单纯的ACK报文长度为0 二、TCP建立连接三次握手和数据传输 1、连接建立三次握手
1、初始状态一开始客户端和服务端都是属于关闭CLOSE状态服务端通过 ServerSocket serverSocket new ServerSocket(8081,1);开启监听LISTEN2、第一步客户端的TCP首先向服务器的TCP发送一个特殊的TCP报文段该报文段被称为SYN报文段。该报文段中不包含应用层数据但是会将TCP报文段首部中的一个标志位即SYN比特设置为1因此这个特殊的报文段被称为SYN报文段另外客户端会随机的生成一个初始序号client_isn,并将此编号放置于该报文段的序列号Seq字段中即Seq client_isnx此时客户端会进入SYS_SEND状态。3、第二步、一旦服务器收到了SYN报文需要确认客户端的报文会将确认报文中的SYN比特设置为1ACK比特设置为1并将该报文中的确认号Ack设置为client_isn1公式2即Ackclient_isn1最后服务器会生成自己的初始序列server_isn并将之放到报文段的序列号字段上即Seqserver_isny该报文表示“我收到了你发起建立连接的SYN分组该分组带有初始序号client_isn我同意建立连接我自己的初始序列是server_isn” 该允许连接的报文段有时被称为SYNACK报文段SYNACK segment此时服务端进入SYN_RECV状态并且该连接进入到syn queue 队列中去4、 第三步、在客户端收到SYNACK报文段后需要对该SYNACK报文段确认需要将ACK设置为1序列号为Seq client_isn1 公式1确认号为Ackserver_isn1公式2因为此时连接已经建立所以SYN被设置为0并且后续的数据发送SYN字段也被设置为0。TCP规定这个报文段可以携带数据也可以不携带数据如果不携带数据那么数据长度就是0根据上述公式1那么下一个数据报文段的序号仍是 seq client_isn 1。这时客户端进入 ESTABLISHED (已连接) 状态。5、服务器收到客户的确认后也进入 ESTABLISHED 状态。
2、数据传输
客户端发送 10 字节的数据通常 TCP 数据报文的控制位是 [PSH, ACK]此时该 TCP 数据报文的序列号和确认号分别设置为
1、序列号设置为 client_isn 1。客户端上一次发送报文是 ACK 报文第三次握手该报文的 seq client_isn 1由于是一个单纯的 ACK 报文没有携带用户数据所以 len 0。根据公式 1序列号 上一次发送的序列号 len可以得出当前的序列号为 client_isn 1 0即 client_isn 1。2、确认号设置为 server_isn 1。没错还是和第三次握手的 ACK 报文的确认号一样这是因为客户端三次握手之后发送 TCP 数据报文 之前如果没有收到服务端的 TCP 数据报文确认号还是延用上一次的其实根据公式 2 你也能得到这个结论。 可以看到客户端与服务端完成 TCP 三次握手后发送的第一个 「TCP 数据报文的序列号和确认号」都是和「第三次握手的 ACK 报文中序列号和确认号」一样的。 如果客户端发送的第三次握手 ACK 报文丢失了处于 SYN_RCVD 状态服务端收到了客户端第一个 TCP 数据报文会发生什么 发送的第一个 「TCP 数据报文的序列号和确认号」都是和「第三次握手的 ACK 报文中序列号和确认号」一样的并且该 TCP 数据报文也有将 ACK 标记位置为 1。所以服务端收到这个数据报文是可以正常完成连接的建立然后就可以正常接收这个数据包了。
三、四次挥手
数据传输阶段结束后客户端发起了 FIN 报文请求服务端端开该 TCP 连接此时就进入了 TCP 四次挥手阶段如下图
1、客户端发起第一次挥手。FIN设置为1ACK设置为1该报文长度为1 序列号为上一次发送的序列号上一次发送的数据长度即Seqclient_isn11; 确认号是上一次收到的报文中的序列号 上一次收到的报文长度len上一次收到的序列号为server_isn1因为上一次收到的是单纯的ACK报文所以长度为0所以Ackserver_isn10server_isn12、服务端发起第二次挥手。ACK设置为1该报文长度为0 序列号为上一次发送的序列号上一次发送的数据长度即Seqserver_isn1因为上一次收到的是单纯的ACK报文所以长度为0所以Seqserver_isn10server_isn1 确认号为上一次收到的报文中的序列号 上一次收到的报文长度len上一次收到的是FIN报文故而长度为1即Ackclient_isn111client_isn12;3、服务端发起第三次挥手。SYN设置为1该报文长度为1 序列号为上一次发送的序列号一上次发送的数据长度因为上一次发送的是单纯的ACK报文所以长度为0即Seqserver_isn10server_isn1 确认号为上一次收到的报文中的序列号 上一次收到的报文长度len上一次收到的序列号是client_isn11因为收到的是FIN报文长度为1所以Ackclient_isn111client_isn124、客户端发起第四次挥手。ACK设置为1该报文长度为0 序列号为上一次发送的序列号一上次发送的数据长度上一次发送的序列号是client_isn11因为发送的是FIN报文长度为1所以Seqclient_isn111client_isn12(上述图中有误请注意懒得改了) 确认号为上一次收到的报文中的序列号 上一次收到的报文长度len上一次收到的序列号为server_isn1报文是FIN报文长度是1即Ackserver_isn11server_isn2(上述图中有误请注意懒得改了)
引用
https://zhuanlan.zhihu.com/p/577528304