Posix api与网络协议栈

目录

一、连接建立

Socket()

Bind()

Listen()

三次握手

思考题

Accept()

二、传输数据

三、断开连接

Close() 和四次挥手

四次挥手特殊情况

P2P的实现

参考资料


主要通过 TCP 连接整个过程来了解 posix api 是如何执行的。

一、连接建立

Socket()

创建 fd 和空的 tcp control block,通过bitmap算法分配fd。

Bind()

通过 fd 找到 tcb 把 ip 和端口设置进去,对于客户端这个函数不是必做的,不调用的话会随机分配端口。

Listen()

a. 将 tcb->status = TCP_STATUS_LISTEN,如果没有监听的话,客户端连接时会报错:connection refused;

b. 为 tcp 连接分配 tcb->syn_queue(半连接队列), tcb->accept_queue(全连接队列)。

在完成监听之后,才到三次握手的过程。

三次握手

Sequence number 双方都会设置一个随机值。它可以用来保证数据包不丢失,不乱序,不重复。

思考题

三次握手的过程,发生在哪些函数里面?

不发生在任何函数里,三次握手是一种被动的由内核协议栈实现的过程,三次握手是由客户端调用 connect 函数发起,accept 函数是三次握手完成以后,取出一个已经建立好的连接。listen完之后服务器才能三次握手。

第一次握手的连接放在半连接(SYN)队列中,第三次握手完成之后将半连接队列中的 tcp 连接move到全连接(ACCEPT)队列中。

Tcp连接的生命周期,从什么时候开始?

连接在第一次握手协议栈分配一个tcp连接的时候,生命周期就已经开始了。Fd是在accept函数创建的。

第三次握手的数据包,如何从半连接队列找到匹配的节点?

从数据包中就能提取到五元组(源ip,源端口,目的ip,目的端口,协议类型)找到对应的节点。

如何防止syn泛洪

通过 Listen(fd, backlog) 中的 backlog 来防止。

Backlog参数不同时期的意义:

Syn队列数量:有效防止泛洪,但是越来越鸡肋,在接收到数据之前已经隔离了,比如防火墙。

Syn + accept队列总长度,未分配的fd的tcb的数量:有效防止accept队列长时间不处理。

Accept 队列长度(现版本):可以大大提升接入量,新建数量(建链的吞吐量)。

Accept()

分配fd给客户端连接,fd与tcb做映射。在 epoll 中,listenfd 用的是水平触发(LT)还是边沿触发(ET),水平触发符合需求,有数据就会取。如果用 ET accept 该如何写呢?循环 accept 直到fd返回 -1。

二、传输数据

send, recv这些函数仅仅是把数据copy到内核当中或者从内核拿出来,这些函数调用和网络传输实际上是异步的。

如下图所示,send发送多次交给协议栈后,由于tcp是面向字节流的,可能会将其合并成一个数据包发送,而对端收到后也不一定一次读完,可能会分多次接收。一次全部接收或发送和多次接收或发送性能的差异其实不大。

慢启动、拥塞控制、滑动窗口、延迟确认、超时重传这些机制都是 tcp 为了保障数据能发送到对方。

三、断开连接

Close() 和四次挥手

回收 fd,发送 fin 包。

如果前面调用 send 的数据和 close 的 fin 包粘在一起也不会有影响,协议栈接收完以后会有两个事件,一次 recv 会把数据读完,再次 recv 返回是0。

四次挥手特殊情况

1. 如果主动关闭方在发送 fin 包后没有收到 ack 直接接收到了对方的 fin,状态如下图所示:

2. 如果双方都在没有收到对方的 fin 之前调用了 close(),状态如下图所示:

服务器出现大量 time_wait 有可能是上述情况。

P2P的实现

如果双方都调用connect(),并且都没有调用listen(),没有服务器,那么双方都是服务器也都是客户端。

代码实现参考这篇文章:linux网络编程5——Posix API和网络协议栈,使用TCP实现P2P通信

参考资料

https://github.com/0voice

linux网络编程5——Posix API和网络协议栈,使用TCP实现P2P通信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值