Posix API
tcp server
socket
创建一个TCB
bind
作用:绑定ip、port到fd, 不调用的话使用默认值(填充五元组),可以理解为设置socket属性
connect
listen(int fd, int backlog)
-
backlog: (unix中)半连接+全连接的总数的最大值, 容易收到DDOS攻击 : (其他)全连接的最大数, 不会遭受DDOS攻击 -
这里面会经历三次握手,接收到连接请求时候将连接信息(五元组)填入半连接队列,并发出sync通知client。当server接收到client的sync的时候,将半连接队列中的对应块信息(五元组)放入全连接队列 -
如果第一次超时没有接收到client的sync, 则server再发一次sync, 再次超时则丢掉
accept
从全连接队列中得到一个tcb控制块 分配文件描述符
recv
发现tcb的recv_buffer中存在了数据,再cp过来 (TCP协议栈执行) tcb每收到一个包,重置延时定时器,发现有包没有收全,比如收到了包序号1,2,3,5,6, tcb回复一个ack=4,client将重新发送4,5,6,以此来确保包的完整性 6. send: 仅将数据cp到tcb的sendbuf中,tcb异步发送数据
close
执行四次挥手(客户端、服务器各自close以及sync,总共4次挥手)
-
fin_wait1附带超时重传,即该状态不会太多。 -
如果close_wait状态较多,大概率是recv到0长度的数据包后没有即时close掉链接,解决方案: 将close之前的流程扔到另外一个线程中处理 -
客户端停留在fin_wait2(对端没有即时调用close),解决方案: 设置keep_alive 字节将之终止掉 -
如果双方同时发送close, 两者同时进入closing状态,各自发送ack,则都进入time_wait状态 -
如果出现大量的time_wait, 可以设置reused, 在简历连接时候 先去reused列表中寻找对应的五元组tcb进行使用
time_wait的回收:时间到了回收 fd的回收:调用close时候回收 tcb的回收:主动close的是time_wait后回收,被动close是收到ack后回收
TCB
可以根据五元组定位到tcb控制块的位置
fcntl
设置socket文件属性, 不涉及协议栈属性变更
TCP与UDP的优劣
TCP重传耗时较大 TCP无法做到实时 UDP速度快 UDP数据传输不够稳定
定时器
重传计时器:Retransmission Timer 坚持计时器:Persistent Timer 保活计时器:Keeplive Timer 时间等待计时器:Time_Wait Timer
|