当前位置: 首页 > 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.dtcms.com/a/317044.html

相关文章:

  • Unity笔记(一)——生命周期函数、Inspector面板、MonoBehavior、GameObject
  • Go语言版JSON转TypeScript接口生成器:支持智能递归解析与命名优化
  • 超细整理,接口测试基础+流程,真实环境下怎么测...
  • [GESP202309 四级] 2023年9月GESP C++四级上机题题解,附带讲解视频!
  • 解锁音频创作新可能:AI 人声伴奏分离神器 Replay 深度解析
  • Python 进行点云ICP(lterative Closest Point)配准(精配准)
  • 【Java String】类深度解析:从原理到高效使用技巧
  • 数论手机辅助:打造便捷高效的移动应用交互体验
  • Wisdom SSH:数据库自动化运维的坚固基石
  • WARNING: Illegal reflective access by org.apache.ibatis.reflection.Reflector
  • 八股——IM项目
  • 多端同步新解法:Joplin+cpolar联合通过开源设计实现跨平台无缝协作?
  • 2025年测绘程序设计模拟赛一--地形图图幅编号及图廓点经纬度计算
  • Python日志记录库——logaid
  • 磁悬浮转子振动控制:主动电磁力如何成为高速旋转的“振动克星”
  • 数据集相关类代码回顾理解 | sns.distplot\%matplotlib inline\sns.scatterplot
  • LeetCode 刷题【31. 下一个排列】
  • Golang 基本数据类型
  • 【vibe coding】Kubernetes + Nginx Ingress 实现云端Workspace容器分配与域名访问方案
  • Linux lvm逻辑卷管理
  • MySQL间隙锁在查询时锁定的范围
  • lesson32:Pygame模块详解:从入门到实战的2D游戏开发指南
  • Python 3.13 预览版:颠覆性特性与实战指南
  • 项目设计模式草稿纸
  • 电感矩阵-信号完整性分析
  • ob数据库是什么
  • 二维数点问题2
  • 计算机视觉的四项基本任务辨析
  • HPE磁盘阵列管理01——MSA和SMU
  • OpenLayers学习(一)-基础