Linux系统编程:传输层(补充)

1. 用UDP实现可靠传输

在前面介绍了UDP是一种不可靠的面向数据包的传输协议。那么如何实现UDP的可靠传输呢?

其实就是在应用层自己实现像TCP一样的可靠性机制:引入序列号、引入确认应答、超时重传、流量控制、拥塞控制等机制。

2. listen系统接口

在之前的socket编程的时候用到了listen接口,想和之socket为监听状态,也是TCP所特有的一个接口;函数原型如下:

int listen(int sockfd, int backlog);

返回值:成功返回0,失败返回-1。

下面就详细讲解一下listen的第二个参数backlog:

基于TCP的客户/服务端程序在三次握手建立链接的时候,会有两个队列

  • 半连接队列:当客户端在向服务端发送SYN想要建立链接时,服务端会在半连接队列中创建一个记录,此时还没有完成三次握手
  • 全连接队列:当三次握手完成后,链接从半连接队列移动到全连接队列

在 Linux 中,backlog 指定了全连接队列的大小,而半连接队列的大小由 tcp_max_syn_backlog 系统参数控制。tcp允许最多有backlog+1个完整的链接被建立。

也就是说在全连接队列中的链接是服务端和客户端是处于established状态的,半连接队列中的链接客户端是处于syn_sent / established状态的,服务端是处于syn_rcvd状态。三次握手完成后,链接建立成功,将链接从半连接队列移入全连接队列,服务端也从syn_rcvd状态变味了establised状态,等待accept调用来取走这个链接。

下图为一个多进程版本的服务器例子,当我们在代码中将backlog设置为2时, 只建立了三个链接,第四个链接的服务端处于syn_recv状态,该链接在半连接队列中。

下面为三次握手的状态变化:

  1. 调用 listen 函数:在服务器端调用 listen 函数后,套接字进入 LISTEN 状态。这是一个被动的状态,表示服务器准备接受连接请求,但并不直接处理连接。listen 函数的成功返回表示套接字已进入 LISTEN 状态,但此时不涉及连接的实际接收和处理。

  2. 客户端发起连接:客户端向服务器发送一个带有SYN标志的TCP连接请求(SYN),这是连接建立的第一步。客户端进入SYN_SEND状态

  3. 服务器接收到SYN请求:服务器端的套接字在 LISTEN 状态时接收到客户端的SYN请求。此时,服务器将这个连接请求放入半连接队列(也称为SYN队列)。连接状态此时是 SYN-RCVD

  4. 处理连接请求:服务器向客户端发送SYN-ACK响应,表示接受连接请求并准备建立连接。

  5. 客户端发送ACK确认:客户端发送ACK响应,完成三次握手。客户端变为ESTABLISHED状态。

  6. 三次握手完成:

    • 当服务器接收到客户端的ACK响应时,连接状态从 SYN-RCVD 变为 ESTABLISHED
    • 此时,连接从半连接队列(SYN队列)移到全连接队列(已连接队列)
  7. accept 函数的作用:服务器应用程序调用 accept 函数来从全连接队列中取出一个已完成三次握手的连接,并为其分配一个新的已连接套接字,用于实际的数据通信。

 

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值