欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > Linux(socket网络编程)I/O缓冲、三次握手、四次挥手

Linux(socket网络编程)I/O缓冲、三次握手、四次挥手

2025/2/22 1:42:02 来源:https://blog.csdn.net/weixin_44050362/article/details/145600248  浏览:    关键词:Linux(socket网络编程)I/O缓冲、三次握手、四次挥手

Linux(socket网络编程)I/O缓冲、三次握手、四次挥手

  • TCP套接字的I/O缓冲
    • I/O缓冲的特性
    • 滑动窗口协议Sliding Window
  • TCP三次握手
    • 提要
  • TCP四次挥手

TCP套接字的I/O缓冲

(1)write函数调用后,并非立即传输数据。
read函数调用后,也不是马上接收数据。
write函数调用时,数据是先被移至输出缓冲;
read函数调用时,数据从输入缓冲读取数据。
(2)write返回的值,是成功写到输出缓冲的字节数。
read返回的值,是成功从输入缓冲读到的字节数。
(3)不同socket所拥有的I/O缓冲是不同的,即使是相同IP、相同端口号。

I/O缓冲的特性

(1)I/O缓冲在每个socket(TCP套接字)中单独存在。
(2)I/O缓冲在创建套接字时自动生成。
(3)关闭套接字后,输出缓冲中的剩余数据会继续传递。
(4)关闭套接字后,会丢弃输入缓冲中的数据。

滑动窗口协议Sliding Window

缓冲大小100,对方却一次发来100字节的数据怎么办?
TCP的滑动窗口协议就是为了解决这样的问题。

TCP中不会因为缓冲溢出而丢失数据。
但会因为缓冲而影响传输效率。

TCP三次握手

提要

TCP连接建立时,分客户端和服务端;
服务端建立步骤:
1.建立套接字、套接字结构体
2.bind函数给套接字绑定地址族、IP(监听的IP)、端口号
3.调用listen函数进行监听
4.accept函数接受连接,完成三次握手
5.write、read 进行通信
客户端建立步骤:
1.建立套接字,套接字结构体
2.设置结构体的地址族、IP(服务端IP),端口号(服务端端口号)
3.调用connect向服务端发起连接,客户端套接字自身的IP和端口号,是通过connect函数自动赋予。

未建立连接时的状态:
服务端:listen
客户端:close

注:下面说的SYN,SYN+ACK表示的是报文,不是参数、、、

第一次握手:
客户端发送SYN报文
SYN报文包含SEQ,假设这里SEQ的初始值为1000;

状态:
服务端:listen
客户端:SYN_SENT

第二次握手:
服务端收到SYN,同意连接,发出SYN+ACK
这里ACK=1001,用来和上述的SEQ=1000对应;
假设这里的SEQ=2000;没错,各自发送的SEQ值是不一样的

状态:
服务端:SYN_RECV
客户端:SYN_SENT

第三次握手:
客户端收到SYN+ACK后,向服务端发送ACK------状态置为ESTABLISHED
服务端收到ACK------状态置为ESTABLISHED
这里回复的SEQ=1001,因为上一次是1000;
回复的ACK=2001,因为上一次接收到的SEQ=2000;

状态:
服务端:ESTABLISHED
客户端:ESTABLISHED

在这里插入图片描述

说明:
(1)上述的SEQ是一个序列号,32位无符号整数类型。而我假设的SEQ=1000、SEQ=2000,这里假设的1000、2000其实就是初始序列号(ISN)。
(2)建立完成后,在后续的数据传递过程中,SEQ也会继续跟随数据段发送,继续递增,用来记录数据段的顺序。
(3)SEQ超过其最大值2^32-1后又回到0继续递增。
(4)上述的状态变化,是基于一个正常完成的TCP三次握手,那要是中间出现什么问题了,比如服务端回复了SYN+ACK,客户端迟迟没有回复ACK;那服务端就会进行重发,一直都不回复就一种重发,直到超时;那么在这个重发的过程中,服务端的相应资源也是被占用的;
(4.1)这样一个机制,就使得有一种针对服务端的攻击:SYN Flood攻击,即客户端伪造很多SYN向服务端请求连接,但刻意不完成第三次握手,占用服务端的连接表、内存等资源。严重时会导致服务端无法正常接受其它请求。
(4.2)防御方法:
》增加资源,治标不治本
》使用防火墙过滤掉恶意的SYN请求
》启用SYN Cookie:服务端接受SYN时不立刻分配内存资源,而是收到客户端的ACK后,验证完成后,才分配内存资源。
》部署入侵检测系统(IDS)和入侵防御系统(IPS):当短时间内接收到大量来自同一源IP的SYN请求时,系统应能自动识别并采取措施。
》部署负载均衡器:负载均衡器可以将流量分散到多台服务器上,从而降低单台服务器的压力。在遭受SYN Flood攻击时,负载均衡器可以快速将流量切换到其他未受影响的服务器上,保证服务的连续性。

TCP的重要机制:
序列号回绕机制、确认应答机制、超时重传机制、窗口控制机制、处理序列号冲突等;

TCP四次挥手

报文:FIN、ACK

角色:主机A、主机B
注意了,挥手的时候,谁主动都可以。

第一次挥手:
A发:FIN------A的状态置为fin_wait_1

状态:
A:fin_wait_1
B:established

第二次挥手:
B发:ACK-------B的状态置为close_wait
A收:ACK------A的状态置为fin_wait_2

状态
A:fin_wait_2
B:close_wait

第三次挥手:
B发:FIN-------B的状态置为last_ack

第四次挥手:
A收:FIN
A发:ACK-------A的状态置为time_wait
B收:ACK-------B关闭连接进入closed状态
而A在time_wait状态滞留一段时间后,没有再收到B的报文,也把状态置为closed

注:FIN和ACK报文中,也包含了seq和ack;

在这里插入图片描述

第二次挥手和第三次挥手都是由被动方发报文;
原因在于:
第二次挥手是告诉主动方:我已经收到你的请求了,但请再等等,我要把我的业务处理完。
第三次挥手是告诉主动方:我这边也完事了,该发的也发完了,咱结束吧。

而最后第四次挥手中,A发送ACK后,还要在time_wait状态等待的原因是:
确保对方确实没有报文要发了,不然要是对方有发出的报文因为延迟而姗姗来迟。A却早早的结束了连接,释放了资源。就无法收到这迟到的报文了。
而如果A已经close了,B的连接却依然存在。那么后续新建立的连接也会受B的旧链接报文的影响。

四次挥手确保了全双工连接的可靠关闭,防止了旧链接数据包对新连接产生干扰。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com