当前位置: 首页 > web >正文

网络编程超时检测,unix域套接字,粘包

刷题:

# 超时检测核心要点
## 1. 基本类型
### 阻塞模式
- 永久等待数据,无超时机制
- 典型函数:`recv()`阻塞调用
### 非阻塞模式
- 立即返回结果(成功/错误)
- 设置方式:`fcntl(fd, F_SETFL, O_NONBLOCK)`
### 超时检测
- 设置等待阈值,超时返回错误
- 应用场景:网络请求、心跳包
---
## 2. 超时检测函数
### select函数
- 参数:`struct timeval`设置秒和微秒
- 示例:
```c
struct timeval tm = {3, 0};
if (select(..., &tm) == 0) { /* 超时处理 */ }

poll函数

  • 参数:超时时间(毫秒)
  • 示例:
    if (poll(fds, 10, 3000) == 0) { /* 超时处理 */ }

epoll_wait

  • 参数:超时时间(毫秒)
  • 示例:
    if (epoll_wait(epfd, events, 10, 3000) == 0) { /* 超时处理 */ }

setsockopt

  • 设置收发超时:
    struct timeval rcv_timeo = {3, 0};
    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &rcv_timeo, sizeof(rcv_timeo));

3. 心跳包机制

核心作用

  • 维持长连接活跃状态
  • 检测客户端存活(TCP/UDP均适用)

实现步骤

  1. 客户端:周期发送空包(如每5秒)
  2. 服务端
    • 维护客户端列表(IP+Port+最后通信时间)
    • 定时任务检测超时(如60秒无响应判定离线)

数据结构

  • 消息类型
    enum type_t { CHAR, HEART }; // 区分业务包和心跳包
  • 时间记录
    typedef struct timebuf {
    unsigned int ip;
    unsigned short port;
    time_t tm; // 最后通信时间戳
    } timebuf_t;

4. 信号处理

alarm函数

  • 周期性触发信号(如每5秒)
  • 示例:
    signal(SIGALRM, handler);
    alarm(5);

sigaction配置

  • 关闭自重启属性
    struct sigaction act;
    sigaction(SIGALRM, NULL, &act); // 获取原属性
    act.sa_flags &= ~SA_RESTART; // 关闭自重启
    sigaction(SIGALRM, &act, NULL); // 设置新属性
  • 超时中断处理
    void handler(int sig) {
    printf("超时中断!");
    // 中断阻塞操作(如recv返回-1,errno=EINTR)
    }

5. 代码实现示例

TCP服务端超时检测

  • 关键步骤:
    1. 创建socket并绑定监听
    2. 使用alarm设置超时信号
    3. recv中捕获超时错误(errno == EINTR

UDP心跳包服务端

  • 核心逻辑:
    while (1) {
    ret = recvfrom(sockfd, &buf, ..., &cliaddr);
    if (ret > 0) {
    update_time(cliaddr); // 更新时间戳
    if (buf.type == HEART) continue; // 心跳包不处理业务
    }
    }

# UNIX域套接字核心要点
## 1. 基本概念
### 本地通信机制
- 通过文件路径而非网络地址通信
- 适用场景:高效本地进程间通信
- 文件类型:`s`类型套接字文件
### 与网络套接字对比
- **网络通信**:自动填充客户端IP+Port
- **域套接字**:需手动绑定路径实现双向通信
---
## 2. TCP域套接字
### 服务端流程
1. **创建套接字**:
```c
socket(AF_UNIX, SOCK_STREAM, 0)
  1. 绑定路径
    struct sockaddr_un addr = {.sun_family=AF_UNIX};
    strcpy(addr.sun_path, "./unix_socket");
    bind(sfd, (struct sockaddr*)&addr, sizeof(addr));
  2. 监听连接
    listen(sfd, 5);
  3. 接受连接
    accept(sfd, NULL, NULL); // 忽略客户端路径

客户端流程

  1. 创建套接字:同服务端
  2. 连接服务端
    connect(cfd, (struct sockaddr*)&server_addr, sizeof(server_addr));

关键函数

  • access():检查文件存在性
  • unlink():删除旧套接字文件避免绑定失败

3. UDP域套接字

服务端实现

  1. 绑定路径:必须显式绑定
    bind(sfd, "./server_socket");
  2. 接收消息
    recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cliaddr, &len);
  3. 发送响应:需客户端路径
    sendto(sfd, buf, strlen(buf), 0, (struct sockaddr*)&cliaddr, len);

客户端实现

  1. 必须绑定路径:否则服务端无法回复
    bind(cfd, "./client_socket");
  2. 发送消息
    sendto(cfd, buf, strlen(buf), 0, (struct sockaddr*)&server_addr, len);

4. 并发与优化

epoll模型应用

  • 非阻塞设置
    fcntl(fd, F_SETFL, O_NONBLOCK);
  • 事件监听
    epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
  • 边缘触发
    event.events = EPOLLIN | EPOLLET;

文件管理

  • 路径冲突处理
    if (access("./socket_file", F_OK) == 0) unlink("./socket_file");

5. 数据结构

地址结构体

struct sockaddr_un {
sa_family_t sun_family; // AF_UNIX
char sun_path[108]; // 套接字文件路径
};

消息格式

typedef struct {
enum { CHAR, HEART } type; // 数据类型标识
char text[128]; // 实际数据
} msgbuf_t;

# TCP粘包问题核心要点
## 基本概念
### 粘包现象定义
- 数据包在传输过程中发生粘连
- 表现为接收端无法区分原始数据边界
### 发生场景
- TCP流式传输固有特性
- 发送/接收缓冲区大小不一致
- 网络传输延迟导致数据堆积
## 核心成因
### 协议特性
- TCP面向字节流的传输方式
- UDP数据报传输天然无粘包
### 应用层因素
- 发送端数据写入过快
- 接收端读取不及时
- 数据包大小与缓冲区不匹配
## 解决方案设计
### 数据封包协议
- 固定包头结构:
```c
typedef struct {
uint32_t length; // 数据长度(网络字节序)
char data[]; // 实际数据
} tcp_packet_t;
  • 包头校验机制(CRC32/MD5)

发送端实现

  1. 数据分片预处理
  2. 添加4字节长度头
  3. 使用htonl转换字节序
  4. 分次发送保证完整性

接收端实现

  1. 先读取4字节包头
  2. ntohl转换获得数据长度
  3. 循环读取直到数据完整
  4. 缓冲区动态扩容机制

代码实现关键点

服务器端核心逻辑

  • 双重接收循环结构
  • 非阻塞读取超时处理
  • 数据完整性校验
  • 异常断开检测机制

客户端核心逻辑

  • 文件分块随机读取
  • 内存预分配策略
  • 数据分片发送保障
  • 错误重传机制

性能优化方向

传输层优化

  • 设置TCP_NODELAY选项
  • 调整SO_SNDBUF/SO_RCVBUF

应用层优化

  • 滑动窗口协议实现
  • 双缓冲区分包处理
  • 异步IO事件驱动模型

错误处理机制

常见异常场景

  • 数据包长度校验失败
  • 接收缓冲区溢出
  • 网络传输中断
  • 字节序转换错误

健壮性设计

  • 心跳包维持连接
  • 数据包重传请求
  • 校验和验证机制
  • 连接异常中断恢复
http://www.xdnf.cn/news/6191.html

相关文章:

  • WPF Datagrid 数据加载和性能
  • Spring的 @Validate注解详细分析
  • 【springcloud学习(dalston.sr1)】Ribbon负载均衡(七)
  • 【行为型之模板方法模式】游戏开发实战——Unity标准化流程与可扩展架构的核心实现
  • 数据库MySQL学习——day10()
  • FFMPEG 与 mp4
  • elpis-core: 基于 Koa 实现 web 服务引擎架构设计解析
  • LeetCode 热题 100_颜色分类(98_75_中等_C++)(技巧)(计数;双指针)
  • git push 报错:send-pack: unexpected disconnect while reading sideband packet
  • 鸿蒙OSUniApp 开发的下拉刷新与上拉加载列表#三方框架 #Uniapp
  • “堆”和“栈”
  • matlab插值方法(简短)
  • 4G物联网模块实现废气处理全流程数据可视化监控配置
  • Android多媒体——媒体解码流程分析(十四)
  • Cursor 0.5版本发布,新功能介绍
  • 从零实现一个高并发内存池 - 2
  • WebGL知识框架
  • 网络协议分析 实验五 UDP-IPv6-DNS
  • openfeign与dubbo调用下载excel实践
  • Python知识框架
  • Idea 设置编码UTF-8 Idea中 .properties 配置文件中文乱码
  • 【大模型】OpenManus 项目深度解析:构建通用 AI Agent的开源框架
  • Ubuntu——执行echo $USE什么都不显示
  • Turborepo + Vite + Next.js + Shadcn Monorepo 项目构建
  • 【JVS更新日志】企业文档AI助手上线、低代码、智能BI、智能APS、AI助手5.14更新说明!
  • Python如何解决中文乱码
  • 驾驭数据洪流:大数据治理的全面解析与实战方案
  • git使用的DLL错误
  • 线性规划求解及演示
  • 项目基于udp通信的聊天室