others-tcp详解
others-tcp详解
前篇
- “三次握手,四次挥手”你真的懂吗?(深度好文) - https://zhuanlan.zhihu.com/p/53374516
- 网络基础 - https://blog.51cto.com/6444936/2339406
- TCP/IP详解–发送ACK和RST的场景 - https://blog.csdn.net/yusiguyuan/article/details/21446309
三次握手,四次挥手 图解
源端口、目标端口:
下层要为上层的协议服务,靠端口号来标识协议类型。
计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过制定源端口和目标端口,就可以知道是哪两个进程需要通信。
程序用多个端口
客户端端口是随机的,服务器端口号是固定的
命令ss –nt 可查看服务器端口编号
文件 /etc/services 可查看常见软件用的端口号
序列号:seq
表示本报文段所发送数据的第一个字节的编号。在TCP链接中所传送的字节流的每个字节都会按顺序编号。由于序列号由32位表示,所以每2^32个字节,就会出现序列号回绕,再次从0开始
客户端的序列号是所有发送数据的编号,在不同的接收端,序列号会从0开始计算,客户端记录的是整体编号。
确认号:ack
表示接收方期望收到发送方下一个报文段的第一个字节数据的编号,也就是告诉发送发:我希望你(指发送方)下次发送的数据的第一个字节数据的编号是这个确认号
数据偏移:
表示TCP报文段的首部长度,共4位,由于TCP首部包含一个长度可变的选项部分,需要指定这个TCP报文段到底有多长。
它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。该字段的单位是32位(即4个字节为计算单位),4位二进制最大表示15,所以数据偏移也就是TCP首部最大60字节
标记位6位
URG:表示本报文段中发送的数据是否包含紧急数据。后面紧急指针段(urgent pointer)只有当URG=1时才有效
ACK:表示前面确认号字段是否有效。只有当ACK=1时,前面的确认号字段才有效。TCP规定,链接建立后,ACK必须为1,带ACK标志的TCP报文段称为确认报文段
PSH:数值为0提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如果为1,则表示对方应当立即把数据提交给长层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在TCP接收缓冲区中
RST:重置位如果收到一个RST=1的报文,用来同步序号。
当SYN=1,ACK=0时,表示这是一个请求建立链接的报文段;
当SYN=1,ACK=1时,表示对方同意建立连接。
SYN=1,说明这是一个请求建立链接或同意建立链接的报文。只有在前两次握手中SYN才置为1,带SYN标志的TCP报文段称为同步报文段
FIN:表示通知对方本端要关闭连接了,标记数据是否发送完毕,如果FIN=1,即告诉对方:“我的数据已经发送完毕,你可以私房连接了”,带FIN标志的TCP报文段称为结束报文段
窗口大小
表示现在允许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量,一个包确认一次,窗口大小为1
固定窗口:固定的一次发送多少包,然后确认一次。
滑动窗口:实验性的并发数个报,看对方的回应几个包,通过协商来确定一次能发多少包
校验和
提供额外的可靠性
紧急指针
标记紧急数据在数据字段中的位置
三次握手
四次挥手
【注意】中断连接端可以是Client端,也可以是Server端。
假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说”我Client端没有数据要发给你了”,但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,”告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息”。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,”告诉Client端,好了,我这边数据发完了,准备好关闭连接了”。Client端收到FIN报文后,”就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,”就知道可以断开连接了”。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!
为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方是否现在关闭发送数据通道,需要上层应用来决定,因此,己方ACK和FIN一般都会分开发送。
TCP 包头
windows socket 踩坑
会有一种情况, server 遇到报错 wsarecv
关闭 socket 的时候, 客户端那边检测不到, 还是 connect 状态
- server 报错:
read tcp 172.19.1.1:111->116.24.1.1:222: wsarecv: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
- server 报错:
read tcp 172.19.1.1:111->116.24.1.1:222: wsarecv: An existing connection was forcibly closed by the remote host.