三次握手和四次挥手(简单C++通讯模型程序内外以及包含简单函数的背后应该知道)

发布时间:2024年01月20日

TCP 是面向连接的、可靠的协议,建立 TCP 连接需要三次对话(三次握手),拆除 TCP 连接需要四次对话(四次握/挥手)。

1.三次握手

服务端调用 listen()函数后进入监听(等待连接)状态,这时候,客户端就可以调用 connect()函数发起 TCP 连接请求,connect()函数会触发三次握手,三次握手完成后,客户端和服务端将建立一个双向的传输通道

p1 来源于网络:

1、客户端对服务端说:我可以给你发送数据吗?
2、服务端回复:ok,不过,我也要给你发送数据。(这时候,客户端至服务端的单向传输通道已
建立)
3、客户端回复:ok。(这时候,服务端至客户端的单向传输通道已建立)

至此喜结良缘,双向通道(奔赴)建立。

p2 来源于网络:

细节:
1)客户端的 socket 也有端口号,对程序员来说,不必关心客户端 socket 的端口号,由系统随
机分配。(socket 通讯中的地址包括 ip 和端口号,但是,习惯中的地址仅指 ip 地址)
2)服务端的 bind()函数,普通用户只能使用 1024 以上的端口,root 用户可以使用任意端口。

3)listen()函数的第二个参数+1 为已连接队列(ESTABLISHED 状态,三次握手已完成但是没有被
accept()的 socket,只存在于服务端)的大小。(在高并发的服务程序中,该参数应该调大一些)
4)SYN_RECV 状态的连接也称为半连接。
5)CLOSED 是假想状态,实际上不存在。

2.四次挥手

断开一个 TCP 连接时,客户端和服务端需要相互总共发送四个包以确认连接的断开。在 socket 编
程中,这一过程由客户端或服务端任一方执行 close()函数触发。

p3 来源于网络:

1)一端(A)对另一端(B)说:我不会给你发数据了,断开连接吧。
2)B 回复:ok。(这时候 A 不能对 B 发数据了,但是,B 仍可以对 A 发数据)
3)B 发完数据了,对 A 说:我也不会给你发数据了。(这时候 B 也不能对 A 发数据了)。
4、A 回复:ok。

p4 来源于网络:

1)主动断开的端在四次挥手后,socket 的状态为 TIME_WAIT,该状态将持续 2MSL(30 秒/1 分
钟/2 分钟)。 MSL(Maximum Segment Lifetime)报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
2)如果是客户端主动断开,TIME_WAIT 状态的 socket 几乎不会造成危害。a)客户端程序的
socket 很少,服务端程序的 socket 很多(成千上万);b)客户端的端口是随机分配的,不存在重用
的问题。
3)如果是服务端主动断开,有两方面的危害:a)socket 没有立即释放;b)端口号只能在 2MSL
后才能重用。

在服务端程序中,用 setsockopt()函数设置 socket 的属性(一定要放在 bind()之前)
int opt = 1;
setsockopt(m_listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

这样,就可以在有时候主动关闭服务端的时候无法重新执行的情况就有了一种解决方法。p1

3.关于连接状态的查看方法

在cenos下可以使用?命令:

netstat -na

如果找不到netstat命令可以使用命令:

yum install net-tools-y

显示错误的话使用这个命令:

yum -y install net-tools 

使用命令

netstat -na|less

可以看到:

重点关注下图标注部分,下半部分是系统内部通讯,不用深究。可以看到很多关键信息,第一列Proto是协议类型有ipv4,ipv6,udp等。第二列和第三列就是接收端和发送端,第四列是本地IP+端口号,第五列是外地IP+端口号,最后就是连接状态了,各个连接状态类型都在上述p1,p3图中。

关于三次握手四次挥手的更多理论细节也是非常有必要的,本文简洁的目的只为入门运用。

文章来源:https://blog.csdn.net/2301_76320385/article/details/135686949
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。