Posix API与网络协议栈的实现原理

面试中协议栈常问的点?

  1. TCP三次握手过程?
  2. TCP四次挥手过程?
  3. 为什么建立连接需要三次握手,断开连接需要四次挥手?
  4. time_wait状态持续时间及原因?
  5. 大量的time_wait和close_wait?
  6. 超时重传和快速重传?
  7. TCP首部长度有哪些字段?
  8. TCP在listen时的参数backlog的意义?
  9. Accept发生在三次握手的哪一步?
  10. 三次握手过程中有哪些不安全性?
  11. TCP和UDP的区别?
    TCP三次握手四次挥手详解

池式结构

  • 线程池
  • 内存池
  • 连接池
  • 请求池

服务端Posix API

  • fd = socket();
  • bind(); fd —>ip, port
  • listen(fd, backlog);
  • clientfd = accept(fd, addr, addrlen);
  • recv();
  • send();
  • close();

客户端Posix API

  • connect();

epoll Posix API

  • epoll_create();
  • epoll_ctl();
  • epoll_wait();

其他

  • shutdown(); (不常用)
  • setsockopt(); (UDP)
  • getsockopt(); (UDP)
  • fctnl(); (控制io阻塞与否)

TCP的三个阶段

  • 建立连接
  • 传输过程
  • 断开连接

UDP主要用在哪里?

  • 大量数据传输,下载,例如迅雷VIP下载时,去除了拥塞控制,使其不受流量控制
  • 实时性很强的场景,游戏
  • DNS协议,例如浏览器请求域名IP时,采用UDP协议,域名服务器的节点与节点之间的数据同步,采用TCP协议

UDP的缺点有哪些?
不稳定
UDP的connect没有传输具体的数据,只是尝试链路是否通畅

TCP数据包头组成
tcp数据包头
TCP三次握手
TCP三次握手

  • 客户端connect()发出连接请求
  • 服务端listen()之后实现第一次握手,listen()将listenfd置为listen的状态,可以进行三次握手
  • 第三次握手之后,服务端运行函数accept()
  • 如何在syn队列里查到数据包所对应的节点?答:通过五元组(sip, dip, sport, dport, proto)确认
  • 节点的生命周期?tcp状态机(11个状态)存到节点里,生命周期到服务端调用close()为止
  • 节点也叫做tcp控制块,tcp block,简称tcb

UDP的并发(底层处理)

  1. 服务端recvfrom(&addr)获取一个客户端的ip和port
  2. 服务端新建一个fd,sendto(fd, )将ip和port发送给客户端
  3. 若第一帧混起来了,则将数据直接返回,超时再次重发
  4. KCP只是基于此框架完成了一层应用协议

TCP数据传输

  1. tcp如何保证顺序?答:超时重传机制,协议栈接收到一个包启动200ms的定时器,再接收到一个包时重置200ms定时器,以此类推,中间一旦超时,就会从1号包检查有哪些包没有到,假设3号包没到,则从3号包开始依次重发
  2. tcp缺点:ack确认时间周期长,已经接收到的包的重发的次数多
  3. 先指数型增长(慢启动),再线性增长发包一定量之后,在现有包的数量基础上降一半再继续增长(拥塞控制)慢启动及拥塞控制
  4. 客户端应用程序的send()成功,并不意味着发送数据包成功,这能代表客户端应用程序的数据成功的拷贝到对应协议栈上,调用copy_from_user将数据从用户空间拷贝到协议栈sendbuffer里,write()同理

TCP四次挥手
TCP四次挥手

  • 协议栈出现大量的time_wait时该怎么做?答:主动方(主动先调用close的一端)才会产生time_wait 1. 这时查看自己的逻辑;2. 通过setsockopt()设置为reuse(重用),使tcb不被释放而重用,一定程度上减少time_wait
  • 协议栈出现大量的close_wait的原因?答:当服务端0 = recv()之后,没有及时close,产生了延迟(可能recv = 0之后有业务代码要处理),可以将业务代码抛给另一个线程进行处理,0 = recv之后,立即close
  • 由于服务端0 = recv()之后,没有及时close,导致客户端处于fin_wait_2的状态,有什么方法可以结束这种状态?答:没有,若强行禁止,只能用kill,操作系统进行回收
  • 协议栈出现大量的fin_wait_1 的原因?答:客户端没有接收到ack包,导致长期处于fin_wait_1的状态
  • 协议栈出现大量的fin_wait_1 该怎么办?答:无解
  • 一般不建议调用shutdown(),若做成单向功能,可考虑调用

TCP的11种状态(关联fd)TCP的11种状态

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
评论 7

打赏作者

牛奶好烫

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值