利用C语言基于poll实现TCP回声服务器的多路复用模型

简介: 此代码仅为示例,展示了如何基于 `poll`实现多路复用的TCP回声服务器的基本框架。在实际应用中,你可能需要对其进行扩展或修改,以满足具体的需求。

利用C语言实现基于 poll的TCP回声服务器,可以高效地处理多个客户端连接,这种模型被称为多路复用。下面是一个精简而专业的指南,展示了如何通过 poll来实现这一目标。

关键概念

  • TCP服务器:一种在网络编程中常用的服务器模型,用于提供可靠的、面向连接的通信。
  • 回声服务器:这种服务器简单地将接收到的数据回发给发送者。
  • poll系统调用poll提供了一种方式,允许程序监视多个文件描述符集合中的事件,是多路复用编程的一种方式。

实现步骤

  1. 初始化服务器

    • 创建一个TCP套接字。
    • 将套接字绑定到服务器地址(IP地址和端口)。
    • 监听套接字,准备接受客户端连接。
  2. 设置 poll

    • 创建 pollfd结构体数组,以跟踪和管理多个套接字。
    • 将监听套接字加入到 pollfd数组中,设置相应的事件为 POLLIN,以表明我们对可读事件感兴趣。
  3. 事件循环

    • 使用 poll系统调用等待事件发生。poll调用将阻塞,直到一个或多个套接字准备好进行I/O操作。

    • 遍历 pollfd数组,检查哪些套接字有事件发生。

      • 如果监听套接字有事件发生,接受新的客户端连接,并将新的套接字添加到 pollfd数组中。
      • 如果是已连接的客户端套接字上有事件发生,读取数据并回发给客户端。如果读取到的数据长度为0(客户端关闭连接),则关闭套接字并从 pollfd数组中移除。
  4. 数据处理

    • 从活跃的客户端套接字读取数据。
    • 将接收到的数据原封不动地发送回客户端。
  5. 清理与资源管理

    • 一旦服务完成,关闭所有打开的套接字。
    • 确保在退出程序前释放所有分配的资源。

示例代码

下面是一个简化的示例代码,展示了如何使用 poll来实现多路复用的TCP回声服务器:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <poll.h>

#define MAX_CLIENTS 10
#define BUFFER_SIZE 1024

int main() {
    int sockfd, newsockfd, portno = 12345;
    struct sockaddr_in serv_addr, cli_addr;
    socklen_t clilen;
    struct pollfd fds[MAX_CLIENTS];
    int nfds = 1, current_size = 0, i, ret;
    char buffer[BUFFER_SIZE];

    // 创建TCP套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("ERROR opening socket");
        exit(1);
    }

    // 绑定到本地地址
    memset((char *)&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("ERROR on binding");
        exit(1);
    }

    // 监听
    listen(sockfd, 5);

    // 初始化pollfd结构
    memset(fds, 0 , sizeof(fds));
    fds[0].fd = sockfd;
    fds[0].events = POLLIN;

    // 循环等待
    while (1) {
        ret = poll(fds, nfds, -1);
        if (ret < 0) {
            perror("ERROR on poll");
            exit(1);
        }

        // 检查是否是新连接
        if (fds[0].revents & POLLIN) {
            clilen = sizeof(cli_addr);
            newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
            if (newsockfd < 0) {
                perror("ERROR on accept");
                continue;
            }
            fds[nfds].fd = newsockfd;
            fds[nfds].events = POLLIN;
            nfds++;
        }

        // 检查数据接收
        for (i = 1; i < nfds; i++) {
            if (fds[i].revents & POLLIN) {
                memset(buffer, 0, BUFFER_SIZE);
                ret = read(fds[i].fd, buffer, BUFFER_SIZE);
                if (ret < 0) {
                    perror("ERROR reading from socket");
                    close(fds[i].fd);
                    continue;
                } else if (ret == 0) {
                    close(fds[i].fd);
                    fds[i].fd = -1; // 标记为不用
                } else {
                    write(fds[i].fd, buffer, ret);
                }
            }
        }
    }

    close(sockfd);
    return 0;
}

此代码仅为示例,展示了如何基于 poll实现多路复用的TCP回声服务器的基本框架。在实际应用中,你可能需要对其进行扩展或修改,以满足具体的需求。

目录
相关文章
|
8月前
|
存储 人工智能 边缘计算
当 AI 进入「算力密集时代」:你的服务器能跑通大模型吗?
本文深入探讨AI服务器在技术落地中的核心瓶颈问题,结合实战经验解析从模型训练到端侧部署的算力优化策略。内容涵盖三大典型场景的算力需求差异、GPU服务器选型的五大反直觉真相、实战优化方法(如混合精度训练与硬件资源监控),以及边缘AI部署挑战和解决方案。同时提供算力弹性扩展策略、模型生命周期管理及合规性建议,帮助读者构建可持续发展的算力体系。文末附有获取更多资源的指引。
670 17
|
8月前
|
存储 弹性计算 测试技术
10分钟私有部署QwQ-32B模型,像购买Ecs实例一样快捷
虽然阿里云提供了基于 IaaS 部署 QwQ-32B 模型的方式,但传统的基于IaaS的部署方式需要用户自行配置环境、安装依赖、优化硬件资源,并解决复杂的网络与存储问题,整个流程不仅耗时耗力,还容易因操作失误导致各种不可预见的问题。 因此,阿里云计算巢提供了基于ECS镜像与VLLM的大模型一键部署方案,通过ECS镜像打包标准环境,通过Ros模版实现云资源与大模型的一键部署,用户无需关心模型部署运行的标准环境与底层云资源编排,10分钟即可部署使用QwQ-32B模型,15分钟即可部署使用Deepseek-R1-70B模型。
|
10月前
|
人工智能 负载均衡 数据可视化
阿里云出手了,DeepSeek服务器拒绝繁忙,免费部署DeepSeek模型671B满血版
阿里云推出免费部署DeepSeek模型671B满血版服务,通过百炼大模型平台,用户无需编码,最快5分钟、最低0元即可完成部署。平台提供100万免费Token,支持DeepSeek-R1和DeepSeek-V3等多款模型调用,有效解决服务器繁忙问题。新手零基础也能轻松上手,享受高效稳定的API调用和自动弹性扩展功能。教程涵盖开通服务、获取API-KEY及配置Chatbox客户端等步骤,详细指引助您快速实现DeepSeek自由。
636 18
|
12月前
|
缓存 网络协议 Java
【JavaEE】——TCP回显服务器(万字长文超详细)
ServerSocket类,Socket类,PrintWriter缓冲区问题,Socket文件释放问题,多线程问题
|
数据可视化 Linux 网络安全
如何使用服务器训练模型
本文介绍了如何使用服务器训练模型,包括获取服务器、访问服务器、上传文件、配置环境、训练模型和下载模型等步骤。适合没有GPU或不熟悉Linux服务器的用户。通过MobaXterm工具连接服务器,使用Conda管理环境,确保训练过程顺利进行。
1844 0
如何使用服务器训练模型
|
网络协议 Java API
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
227 2
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
191 1
|
存储 PyTorch API
NVIDIA Triton系列09-为服务器添加模型
本文介绍了如何为NVIDIA Triton模型仓库添加新模型。通过示例模型`inception_graphdef`的配置文件`config.pbtxt`,详细解释了模型名称、平台/后端名称、模型执行策略、最大批量值、输入输出节点及版本策略等配置项。内容涵盖了模型的基本要素和配置细节,帮助读者更好地理解和使用Triton服务器。
299 0
|
机器学习/深度学习 人工智能 并行计算
StableDiffusion-01本地服务器部署服务 10分钟上手 底显存 中等显存机器 加载模型测试效果 附带安装指令 多显卡 2070Super 8GB*2
StableDiffusion-01本地服务器部署服务 10分钟上手 底显存 中等显存机器 加载模型测试效果 附带安装指令 多显卡 2070Super 8GB*2
301 0
|
网络协议 Python
Python创建一个TCP服务器
Python创建一个TCP服务器
158 0