POSIX API与协议栈

本文详细介绍了TCP连接中的三次握手过程,包括客户端和服务端的交互,以及传输控制块(TCB)的作用。同时,解释了数据发送时的细节,如内核协议栈的sendbuffer和recvbuffer,以及如何通过延迟ACK保证数据有序。此外,还深入解析了四次挥手的断开连接过程,涉及各种状态如fin_wait_1、fin_wait_2、close_wait和time_wait,并讨论了可能的超时和重传情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Socket

TCB:传输控制块的数据结构把发给不同设备的数据封装起来。建立sokcet时,其实是在分配TCB空间,用户操作的时候操作fd,其实底层是操作tcb。

TCB其实是个五元组的结构体:(客户端IP,客户端端口,本地IP,本地端口,协议)组成

三次握手

三次握手是在客户端发起connect时进行建立的,客户端调用connect函数,内核协议栈发送tcp的包,seqnum=1234代表的是包的数据起始位置,服务器会回一个acknum=1235,代表着1235之前的数据包都已经接受到了,还有发送一个seqnum=3246代表着服务端tcp包的位置,此时客户端会回一个ack;到此三次握手已经建立完毕。

当建立三次握手时,客户端第一次发送,服务端会建立相应的半连接队列,保存相应的tcb;当客户端第二次回应时,会将相应的tcb保存到全连接队列中,此时accpet就是从全连接队列中取相应的tcb与文件句柄建立关系


数据发送

send过程:调用send只是将用户态的数据拷贝到内核协议栈中的sendbuffer当中,内核协议栈什么时候发送,则是有内核决定与用户态无关;sendbuffer中的数据加上tcp头,ip头,网络头组成一个包发送到服务端,服务端接受到数据放入到recvbuffer当中,recv则是将内核栈中的数据拷贝到用户态当中;当send函数返回值为-1时,说明sendbuffer中已经满了,不能再填充了;当recvbuffer中的数据满了时,用户态还没有取数据,则通知客户端窗口为0,说明告诉客户端不要再发送数据了。

为了保证数据在服务端是有序的,我们采用延迟ACK的方法

 

比如客户端发送五个包,当服务端接受到一个包时,会启动相应的定时器,比如200ms,第二个包到的时候,定时器重新定为200ms,第五个包接受到了,但是第六个包在200ms之内没有接受到,则服务端会返回一个ACK,此时ACK=4,说明1,2,3包也接受到了,此时虽然5号包到了,但是也只能重传5号包,从4号包开始。这就保证了每次接受到的是有序的


四次挥手 

当客户端调用close时,内核协议栈发送tcp包其中fin位位1,当服务端接受到fin=1的包时,会想用户态推一个空包,recv=0,发并发送一个确定的ACK包;过了一段时间后服务端调用close时,也会想客户端发送一个fin=1的tcp包,并且客户端返回一个ack到此四次挥手介绍,这个连接再也没有用了。

当客户端调用close时,进入fin_wait_1状态,服务端接受到tcp包后进入close_wait状态;当客户端接受到ack并且到接受到服务端也发送的tcp包这段时间是fin_wait_2状态,服务端调用close后进入last_ack状态。当客户端进入fin_wait_1状态超时了,就会重传,但是大部分会阻塞在fin_wait_2状态,可能在服务端调用close时,要进行一些列的操作比如关闭相应的数据库等。当服务端调用close时会回收相应的fd与tcb,而客户端是在time_wait状态下进行回收

还有一种情况,服务端在调用close时服务端断电了,客户端会一直进入fin_wait_2状态,等待超过2分钟就自动断开;当最后一个ack丢失时,也会进行重传,time_wait时间为120s

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值