Posix API与协议栈

12 篇文章 1 订阅

每个linux的机器自多只有65535个端口, 为什么能做C1000K的连接?

因为 fd  <-> tcb 是一一对应的关系, 而每个tcb都是由五元组来决定的,所以只要是五元组足够多,连接就可以建立;

五元组: remoteip, remoteport, localip, localport, proto

Posix API

 TCB: TCP Control Block

 linux中socket 都会被抽象成file(一切皆文件),TCB也会和file关联在一起,一个TCB就是一个TCP连接, TCB是一个抽象。TCB中包括 connection的状态、接收窗口、拥塞窗口、数据报文的序列号等等。

内核中为每个socket,都会创建2个缓冲区:

1. send buffer: 发送缓冲区

2. receive buffer: 接收缓冲区

1. socket()

socket会在内核创建一个fd 和一个TCB

2. bind(listenfd, struct sockaddr, sizeof(struct sockaddr)

绑定一个IP和端口(0.0.0.0:5678), 在内核中就和一个五元组关联在一个连接。

五元组: remoteip, remoteport, localip, localport, proto

3. listen()函数

listen(fd, backlog);

backlog的含义有2中说法:

1. 半连接队列+全连接队列的和不超过backlog

2. 全连接队列的和不超过backlog(一般情况下,backlog指的是这种说法)。

4. connect函数

connect函数会触发一个syn报文,在服务区端收到syn报文后,会为该连接建立一个TCB,并把TCB加入到半连接队列(syn队列),并发送syn + ack报文到客户端;

当客户端收到 syn + ack 报文后, 发送 ack 报文到服务器端,服务器端收到 ack 报文后会通过五元组从半连接队列中查找已经存在的TCB,找到后加入到全连接队列中。

  • 半连接队列:也叫syn半连接队列
    • syn半连接队列的大小是内核参数控制的,有些内核版本似乎也受listen(fd, backlog)函数的backlog参数的影响,取两者之间的最小值。 该内核参数是:
      • linux@linux:~$ cat /proc/sys/net/ipv4/tcp_max_syn_backlog
      • 256
        linux@linux:~$

  • 全连接队列:也叫accept半连接队列
    • 该队列的大小是 backlog 和 内核参数共同决定的,取其最小值。该参数为:
      • linux@linux:~$ cat /proc/sys/net/core/somaxconn
        128
        linux@linux:~$

    • 当accept队列满时,协议栈的行为有内核:/proc/sys/net/ipv4/tcp_abort_on_overflow 决定

      • tcp_abort_on_overflow 为 1:rver 在收到 SYN_ACK 的 ACK 包后,协议栈会丢弃该连接并回复 RST 包给对端,这个是 Client 会出现(connection reset by peer)错误。

      • tcp_abort_on_overflow 为 0:server 在收到 SYN_ACK 的 ACK 包后,直接丢弃该 ACK 包。这个时候 Client 认为连接已经建立了,一直在等 Server 的数据,直到超时出现 read timeout 错误。

acknum 1235, 表示确认已经收到1235之前的所有数据

TCP延迟ACK机制:

定义:TCP协议中,接收方成功接收到数据后,会回复一个ACK数据包,表示已经确认接收到ACK确认号前面的所有数据。ACK字段长度为32位,能表示0~2^32-1之间的值。

作用:发送方一定时间内,如果没有收到对端的ACK确认报文,会重传TCP报文。

ACK延迟确认机制:接收方收到数据后,并不会立即回复ACK,而是延迟一定时间。ACK延迟发送的时间一般200ms。通过系统的一个定时器每隔200ms来检查是否需要发送ACK,且可以合并发送或者伴随数据一起发送带有ACK的报文,已到达较低网络流量的目的。

5. accept函数

int clientfd = accept();

1. 从全连接队列中取出一个TCB结点

2. 为TCB结点分配一个fd返回。

6. send/recv 函数

UDP的使用场景:

1. 网络环境不好的情况下,重传较多的时候;

2. 数据的实时性要求较高的时候;

7. close 函数

close函数会触发tcp协议发送 fin 报文,

如果出现 fin_wait_1 状态,客户端会重传该报文;

如果服务器端出现大量的 close_wait 状态, 说明服务器端没有调用 close 函数,或者在接收处理过程和close 函数之间的处理过程时间比较长,修改把业务的逻辑处理抛到专门的线程去处理。

如果服务器出现 fin_wait_2 状态,如何解决?

设置TCP协议的keep alive,则可以解决该问题。

如果双方同时发送 fin 报文,

 如果服务器出现大量的 time_wait 状态的报文,如何解决?

设置TCP连接复用 TCP Connection Reuse

vi /etc/sysctl.conf

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1        表示开启重用TIME-WAIT sockets重新用于新的TCP连接
net.ipv4.tcp_tw_recycle = 1        TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

net.ipv4.tcp_timestamps = 1

net.ipv4.tcp_fin_timeout = 30        系統默认的TIMEOUT时间

sysctl -p

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目介绍】 课程作业基于c++实现收发并解析TCPIP协议栈中的数据包源码+项目说明.zip课程作业基于c++实现收发并解析TCPIP协议栈中的数据包源码+项目说明.zip 介绍 - 实现监听主机上的网络适配器 - 使用选定的网络适配器收发数据报 - 截获并分析TCP/IP网络协议栈中的各层协议 最终,本项目实现的功能有: - 获取主机上的所有适配器 - 监听某个网络适配器,可以指定过滤规则 - 截获并分析TCP/IP网络协议栈中的各层协议数据包(包括以太网MAC帧、ARP请求分组、IP数据报、TCP报文段、UDP报文段、ICMP报文段) - 将统计信息和数据输出到文件 ### 题目 项目2:发送和接收TCP数据包 (a) TCP数据包结构设计; (b) TCP数据包发送和接收过程。 TCP是一种面向连接的、可靠的传输层协议。TCP协议工作在网络层IP协议的基础上。本项目的目的是设计一个发送和接收TCP数据包的程序,其功能是填充一个TCP数据包,发送给目的主机,并在目的主机接收此TCP数据包,将数据字段显示显示在标准输出上。 ### 软件架构 - TcpSender下是发送方源码 - TcpReceiver下是接收方源码 - com-headers下是公用头文件和API ### 开发环境 - Visual Studio 2022 - Npcap 1.73 - Npcap 1.13 SDK ## 使用说明 自行安装和配置Npcap,Linux环境下libpcap不够完善,不过UNIX环境直接使用POSIX标准下的socket就行 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通。 2、项目适用人群:计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等计算机相关专业的在校学生、专业老师、行业内企业员工下载使用。 3、项目可用于:项目本身具有较高的学习借鉴价值,不仅适用于小白学习进阶,也可用于专业人员二次开发。当然也可作为毕设项目、课程设计、课程大作业、初期项目立项演示等。 4、如果基础还行,或者热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载使用,相互学习,共同进步!

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值