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

Linux网络编程基础-简易TCP服务器框架

1. 引入头文件

#include<iostream>        
#include<sys/types.h>     // 系统数据类型(如 pid_t、size_t)
#include<sys/socket.h>    // socket 函数及数据结构(socket(), bind(), listen() 等)
#include<netinet/in.h>    // sockaddr_in 结构体定义,IPV4 地址
#include<arpa/inet.h>     // IP 地址转换函数(inet_pton)
#include<signal.h>        // 信号处理(signal())
#include<unistd.h>        // POSIX 系统调用,如 close(), sleep()
#include<stdlib.h>        // 标准库函数,如 atoi()
#include<assert.h>        // assert() 断言函数,用于调试
#include<string.h>        // 字符串函数,如 bzero()

2. 全局变量与信号处理

static bool stop = false; // 全局标志变量,控制主循环是否退出

handle_term(int sig):信号处理函数

static void handle_term(int sig)
{stop = true;
}
  • 参数 sig 是信号编号(比如 SIGTERM 对应 15)。
  • 这个函数的作用是:当接收到某个信号(如 kill -15)时,把 stop 设置为 true,让主循环停止。

3. 主函数部分

函数声明和参数

int main(int argc, char* argv[])
  • argc:命令行参数个数(包括程序本身)
  • argv[]:命令行参数数组(argv[0] 是程序名)

例如运行:

./myserver 127.0.0.1 8888 5
  • argc = 4
  • argv[1] = "127.0.0.1"
  • argv[2] = "8888"
  • argv[3] = "5"

注册信号处理函数

signal(SIGTERM, handle_term);
  • 作用:当收到 SIGTERM 信号(编号 15)时,调用 handle_term()
  • 实现优雅关闭服务器(如用户 kill 程序时能正常释放资源)

检查参数是否合法

if(argc <= 3)
{std::cout << "usage: " << basename(argv[0]) << " ip_address port_number backlog" << std::endl;return 1;
}
  • 如果参数不足,输出用法提示并退出。

  • basename(argv[0]) 返回程序名(不含路径)

  • 示例输出:

    usage: myserver 127.0.0.1 8888 5
    

解析命令行参数

const char* ip = argv[1];        // 获取 IP 字符串
int port = atoi(argv[2]);        // 将字符串转为 int 类型的端口号
int backlog = atoi(argv[3]);     // 将字符串转为 int 类型的连接队列大小
  • atoi()(ASCII to int)将字符串转换为整数
  • backlog 控制的是 listen() 函数中最多能有多少个“未accept的连接”排队

创建 socket 套接字

int sock = socket(PF_INET, SOCK_STREAM, 0);
assert(sock >= 0);
socket() 参数解释:
int socket(int domain, int type, int protocol);
参数含义
domainPF_INET使用 IPv4 协议族(也可写 AF_INET,等价)
typeSOCK_STREAM表示使用 TCP(面向连接)
protocol0默认协议(TCP 默认就是 0)
  • 成功返回 socket 文件描述符(int 型)
  • assert() 确保创建成功,否则程序直接崩溃(用于调试)

创建并初始化地址结构

struct sockaddr_in address;
bzero(&address, sizeof(address));    // 将地址结构全部清零
address.sin_family = AF_INET;        // 协议族:IPv4
inet_pton(AF_INET, ip, &address.sin_addr); // 将 IP 字符串转为网络字节序整数
address.sin_port = htons(port);      // 将主机字节序转为网络字节序
说明:
  • sockaddr_in 是用于 IPv4 的 socket 地址结构。

  • bzero()memset(&address, 0, sizeof(address)) 的简化版,作用是清空结构体。

  • inet_pton(AF_INET, ip, &address.sin_addr)

    • 将 IP 地址字符串(如 “127.0.0.1”)转为网络字节序(用于通信)
  • htons(port)

    • 将主机字节序的端口号转为网络字节序(统一使用大端)

绑定地址

int ret = bind(sock, (struct sockaddr*)&address, sizeof(address));
assert(ret != -1);
bind() 参数:
int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
  • sockfd:socket 描述符
  • addr:地址结构(需要强转为 sockaddr*
  • addrlen:地址结构大小

作用:把 socket 绑定到你指定的本地地址(IP + 端口号)


开始监听连接

ret = listen(sock, backlog);
assert(ret != -1);
listen() 参数:
int listen(int sockfd, int backlog);
  • sockfd:socket 描述符
  • backlog:等待连接的队列长度(最大连接排队数)

作用:把 socket 变为监听状态,准备接受客户端连接


主循环逻辑(等待 SIGTERM)

while(!stop)
{sleep(1);
}
  • 死循环中每秒 sleep 一下(CPU 负载低)
  • 一旦收到 SIGTERM(stop == true),跳出循环
  • 注意这里没有真正处理任何连接,只是为了演示信号控制退出流程

程序清理和退出

close(sock);
return 0;
  • close(sock):关闭 socket,释放资源
  • return 0:正常退出程序

总结:完整程序做了什么?

步骤作用
创建 socket建立 TCP 套接字
设置地址结构设置 IP、端口
bind把 socket 绑定到地址
listen开始监听
signal 注册收到信号时修改 stop 标志
while 循环不断 sleep,等待信号中断
close收到信号后关闭 socket,退出程序

测试

在这里插入图片描述
在这里插入图片描述

http://www.lryc.cn/news/611694.html

相关文章:

  • 服务器——“查询不到显卡驱动,且输入nvidia-smi报错”的解决办法
  • Docker的安装,服务器与客户端之间的通信
  • copy_file_range系统调用及示例
  • 【网络运维】Linux:简单DHCP服务器的部署
  • Profinet转Ethernet IP网关接入五轴车床上下料机械手控制系统的配置实例
  • 03-mysql/redis/apache安装记录
  • 开疆智能ModbusTCP转Profinet网关连接安川YRC1000机器人配置案例
  • PHP官方及第三方下载地址全指南(2025最新版)
  • apache-superset config.py、superset_config.py完整配置项解读
  • SQL的条件查询
  • SQL120 贷款情况
  • CSS高频属性速查指南
  • 基于智能体技术的AIGC源码
  • ABP VNext + SQL Server Temporal Tables:审计与时序数据管理
  • 从 0 到 1:写一个能跑在大体量应用后台的 C++ 协程库
  • 怎么免费建立自己的网站步骤
  • Docker 数据存储路径(解决默认docker路径位置磁盘空间不足的情况)
  • 家庭宽带中的服务器如何被外网访问?
  • RequestBodyAdviceAdapter是什么有什么用
  • [Linux]学习笔记系列 -- [arm][debug]
  • MCP 协议:AI 时代的 “万能转接头”,从 “手动粘贴” 到 “万能接口”:MCP 协议如何重构 AI 工具调用规则?
  • Linux 中 Git 操作大全
  • Go语言 单元测试
  • 鸿蒙app 开发中 全局弹窗类的封装 基于PromptAction
  • LazyLLM教程 | 第3讲:大模型怎么玩:用LazyLLM带你理解调用逻辑与Prompt魔法!
  • AI_提示词Prompt
  • MCP-PromptX AI小说创作使用教程
  • 百度智能云给“数字人”发工牌
  • 纯血鸿蒙(HarmonyOS NEXT)应用开发完全指南
  • HarmonyOS 5 入门系列-鸿蒙HarmonyOS示例项目讲解