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

2024-02-11 多进程、多线程 work

1. 创建一个多进程服务器和多线程服务器

a. 多进程

#include<myhead.h>
#define PORT 9999                  //端口号
#define IP "192.168.125.113"        //IP地址//定义信号处理函数,用于回收僵尸进程
void handler(int signo)
{if(signo == SIGCHLD){while(waitpid(-1, NULL, WNOHANG) > 0 );}
}//定义处理客户端操作的函数
int deal_cli_msg(int newfd, struct sockaddr_in cin)
{//5、收发数据char rbuf[128] = "";    //读取消息的容器while(1){//清空内容bzero(rbuf, sizeof(rbuf));int res = recv(newfd, rbuf, sizeof(rbuf), 0);if(res == 0){printf("客户端下线\n");break;}printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), rbuf);//链接一个字符串后发回去strcat(rbuf, "*_*");send(newfd, rbuf, sizeof(rbuf), 0);//功能:向newfd文件描述符中以阻塞形式写入数据}close(newfd);return 0;
}/**********************************主程序***************************************/
int main(int argc, const char *argv[])
{//将SIGCHLD信号与信号处理函数进行绑定if(signal(SIGCHLD, handler) == SIG_ERR){perror("signal error");return -1;}//1、创建套接字int sfd = -1;//功能创建一个支持TCP通信的套接字//AF_INET:表示跨主机的IPv4的通信//SOCK_STREAM:表示支持TCP通信if((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("socket error");return -1;}printf("sfd = %d\n", sfd);           //?//设置端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1){perror("setsockopt error");return -1;}//2、绑定地址信息结构体(必须)//2.1 填充地址信息结构体struct sockaddr_in sin;sin.sin_family =     AF_INET;   //地址族为IPv4sin.sin_port =         htons(PORT);    //端口号,需要转换网络字节序sin.sin_addr.s_addr = inet_addr(IP);  //IP地址//2.2绑定工作if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("bind error");return -1;}printf("bind success _%d_%s_%s\n", __LINE__, __FILE__, __func__);//3、将套接字设置成被动监听状态if(listen(sfd, 128) == -1){perror("listen error");return -1;}printf("listen success _%d_%s_%s\n", __LINE__, __FILE__, __func__);//4、接收链接请求//4.1 定义用于接收客户端地址信息的结构体变量struct sockaddr_in cin;socklen_t socklen = sizeof(cin);                //接收长度//4.2 接收客户端链接请求int newfd = -1;         //用于跟客户端通信的套接字文件描述符pid_t pid = -1;          //接收子进程pid号while(1){//fork()接收客户端链接请求//当执行到accept时,系统会给该函数预分配一个文件描述符(按最小未使用原则)//所以,在该函数阻塞时,即使有旧的客户端退,释放了文件描述符,也不会再使用新释放的文件描述符//下一次阻塞时,会预选上一次释放的文件描述符if( (newfd=accept(sfd, (struct sockaddr*)&cin, &socklen)) == -1){perror("accept error");return -1;}printf("[%s:%d] 连接成功, newfd = %d\n", inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port), newfd);             //?//创建子进程用于跟新的客户端进行通信工作pid = fork();if(pid > 0){//父进程用于接收客户端连接请求//父进程中关闭newfdclose(newfd);}else if(pid == 0){//关闭sfdclose(sfd);//调用处理客户端信息的函数deal_cli_msg(newfd, cin);//退出子进程exit(EXIT_SUCCESS);}else {perror("fork error");return -1;}//wait(NULL);           //不能使用阻塞方式回收}//关闭套接字close(sfd);return 0;
}

b. 多线程

#include<myhead.h>
#define PORT 9999                  //端口号
#define IP "192.168.125.113"        //IP地址//定义向线程体中传递参数的结构体类型
struct pthread_ds
{int newfd;          //处理客户端的套接字文件描述符struct sockaddr_in cin;       //客户端套接字地址信息结构体变量
};//定义线程处理函数
void *deal_cli_msg(void *arg)
{//分解传过来的参数int newfd = ((struct pthread_ds*)arg)->newfd;     struct sockaddr_in cin = ((struct pthread_ds*)arg)->cin;//5、收发数据char rbuf[128] = "";    //读取消息的容器while(1){//清空内容bzero(rbuf, sizeof(rbuf));int res = recv(newfd, rbuf, sizeof(rbuf), 0);if(res == 0){printf("客户端下线\n");break;}printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), rbuf);//链接一个字符串后发回去strcat(rbuf, "*_*");send(newfd, rbuf, sizeof(rbuf), 0);//功能:向newfd文件描述符中以阻塞形式写入数据}close(newfd);//退出线程pthread_exit(NULL);}/****************************主程序***********************/
int main(int argc, const char *argv[])
{//1、创建套接字int sfd = -1;//功能创建一个支持TCP通信的套接字//AF_INET:表示跨主机的IPv4的通信//SOCK_STREAM:表示支持TCP通信if((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("socket error");return -1;}printf("sfd = %d\n", sfd);           //?//设置端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1){perror("setsockopt error");return -1;}//2、绑定地址信息结构体(必须)//2.1 填充地址信息结构体struct sockaddr_in sin;sin.sin_family =     AF_INET;   //地址族为IPv4sin.sin_port =         htons(PORT);    //端口号,需要转换网络字节序sin.sin_addr.s_addr = inet_addr(IP);  //IP地址//2.2绑定工作if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("bind error");return -1;}printf("bind success _%d_%s_%s\n", __LINE__, __FILE__, __func__);//3、将套接字设置成被动监听状态if(listen(sfd, 128) == -1){perror("listen error");return -1;}printf("listen success _%d_%s_%s\n", __LINE__, __FILE__, __func__);//4、接收链接请求//4.1 定义用于接收客户端地址信息的结构体变量struct sockaddr_in cin;socklen_t socklen = sizeof(cin);                //接收长度//4.2 接收客户端链接请求int newfd = -1;         //用于跟客户端通信的套接字文件描述符pthread_t tid = -1;       //接收线程号while(1){//接收客户端链接请求if( (newfd=accept(sfd, (struct sockaddr*)&cin, &socklen)) == -1){perror("accept error");return -1;}printf("[%s:%d] 连接成功, newfd = %d\n", inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port), newfd);             //?//定义一个向线程体传递的结构体变量struct pthread_ds info = {newfd, cin};//创建一个分支线程,用于跟客户端进行通信if(pthread_create(&tid, NULL, deal_cli_msg, &info) != 0){printf("tid create error\n");return -1;}//回收线程资源//pthread_join(tid);    //不能使用阻塞形式回收线程资源pthread_detach(tid);        //将线程设置成分离态}//关闭套接字close(sfd);return 0;
}

相关文章:

2024-02-11 多进程、多线程 work

1. 创建一个多进程服务器和多线程服务器 a. 多进程 #include<myhead.h> #define PORT 9999 //端口号 #define IP "192.168.125.113" //IP地址//定义信号处理函数&#xff0c;用于回收僵尸进程 void handler(int signo) {if(signo S…...

详解结构体内存对齐及结构体如何实现位段~

目录 ​编辑 一&#xff1a;结构体内存对齐 1.1对齐规则 1.2.为什么存在内存对齐 1.3修改默认对齐数 二.结构体实现位段 2.1什么是位段 2.2位段的内存分配 2.3位段的跨平台问题 2.4位段的应用 2.5位段使用的注意事项 三.完结散花 悟已往之不谏&#xff0c;知来者犹可…...

Linux网络编程——tcp套接字

文章目录 主要代码关于构造listen监听accepttelnet测试读取信息掉线重连翻译服务器演示 本章Gitee仓库&#xff1a;tcp套接字 主要代码 客户端&#xff1a; #pragma once#include"Log.hpp"#include<iostream> #include<cstring>#include<sys/wait.h…...

【计算机网络】协议层次及其服务模型

协议栈&#xff08;protocol stack&#xff09; 物理层链路层网络层运输层应用层我们自顶向下&#xff0c;所以从应用层开始探究应用层 协议 HTTP 提供了WEB文档的请求和传送SMTP 提供电子邮件报文的传输FTP 提供两个端系统之间的文件传输报文&#xff08;message&#xff09;是…...

prometheus之redis_exporter部署

下载解压压缩包 mkdir /opt/redis_exporter/ cd /opt/redis_exporter/ wget http://soft.download/soft/linux/prometheus/redis_exporter/redis_exporter-v1.50.0.linux-amd64.tar.gz tar -zxvf redis_exporter-v1.50.0.linux-amd64.tar.gz ln -s /opt/redis_exporter/redis_…...

js 解构赋值

搬运&#xff1a;JavaScript系列之解构赋值_js解构赋值-CSDN博客...

Vivado用ILA抓波形保存为CSV文件

将ILA观察到的波形数据捕获为CSV文件&#xff0c;抓10次&#xff0c;把文件合并&#xff0c;把源文件删除 运行方法&#xff1a;Vivado的 Tcl console 窗口输入命令 set tcl_dir F:/KLD_FPGA/Code/sim set tcl_filename TCL_ILA_TRIG_V1.2.tcl source $tcl_dir/$tcl_filenam…...

微软AD域替代方案,助力企业摆脱hw期间被攻击的窘境

在红蓝攻防演练&#xff08;hw行动&#xff09;中&#xff0c;AD域若被攻击成功&#xff0c;是其中一个扣分最多的一项内容。每年&#xff0c;宁盾都会接到大量AD在hw期间被攻击&#xff0c;甚至是被打穿的企业客户。过去&#xff0c;企业还会借助2FA双因子认证加强OA、Exchang…...

Git教程I

Git教程I 本地Git创建git仓库将修改存到暂存区将暂存区提交到当前分支查看提交历史回退版本恢复到更晚的版本创建新分支切换分支简单的分支合并冲突分支合并不使用fast forward: --no-ff 远程Git连接远程仓库将本地分支上传到远程仓库从远程仓库拉取 本地Git 学习如何使用本地…...

containerd中文翻译系列(十)镜像验证

下面将介绍默认的 "bindir"ImageVerifier插件实现。 要启用图像验证&#xff0c;请在 containerd 配置中添加类似下面的一段&#xff1a; [plugins][plugins."io.containerd.image-verifier.v1.bindir"]bin_dir "/opt/containerd/image-verifier/b…...

假期day9(2024/2/14)

获取数据库查询的值并调用值使用函数&#xff1a;sqlite3_get_table 在回调函数中获取数据库查询值&#xff0c;无法在其他函数调用&#xff1a;使用函数sqlite3_exec(db, sql, select_callback, &flag, &errmsg&#xff09; 创建表 create table if not exists 表名…...

Leetcode 674 最长连续递增序列

题意理解&#xff1a; 给定一个未经排序的整数数组&#xff0c;找到最长且 连续递增的子序列&#xff0c;并返回该序列的长度。 连续递增的子序列 可以由两个下标 l 和 r&#xff08;l < r&#xff09;确定&#xff0c;如果对于每个 l < i < r&#xff0c;都有 nums[i…...

力扣题目训练(8)

2024年2月1日力扣题目训练 2024年2月1日力扣题目训练404. 左叶子之和405. 数字转换为十六进制数409. 最长回文串116. 填充每个节点的下一个右侧节点指针120. 三角形最小路径和60. 排列序列 2024年2月1日力扣题目训练 2024年2月1日第八天编程训练&#xff0c;今天主要是进行一些…...

理解JAVA EE设计模式

理解JAVA EE设计模式 在Web应用程序的设计和开发阶段,开发人员在开发类似的项目时可能会遇到相似的问题。每名开发人员可能会遇到的问题找出不同或相似的解决方案。但是,这导致一些时间和精力浪费在为相似的问题寻找解决方案上。因此,要啊节省时间和精力,需要记录常见问题…...

GEE:梯度提升树(Gradient Boosting Tree)回归教程(样本点、特征添加、训练、精度、参数优化)

作者:CSDN @ _养乐多_ 对于分类问题,这个输出通常是一个类别标签 ,而对于回归问题,输出通常是一个连续的数值。回归可以应用于多种场景,包括预测土壤PH值、土壤有机碳、土壤水分、碳密度、生物量、气温、海冰厚度、不透水面积百分比、植被覆盖度等。 本文将介绍在Google…...

k8s-资源限制与监控 15

资源限制 上传实验所需镜像 Kubernetes采用request和limit两种限制类型来对资源进行分配。 request(资源需求)&#xff1a;即运行Pod的节点必须满足运行Pod的最基本需求才能 运行Pod。 limit(资源限额)&#xff1a;即运行Pod期间&#xff0c;可能内存使用量会增加&#xff0…...

【Ubuntu】在.bashrc文件中误设置环境变量补救方法

这里是vim也不在PATH中了&#xff0c;因为 解决方法就是在输入vim之后提示的vim路径下用vim打开该文件&#xff0c;然后改回来...

Imgui(1) | 基于imgui-SFML改进自由落体小球

Imgui(1) | 基于imgui-SFML改进自由落体小球 0. 简介 使用 SFML 做2D图形渲染的同时&#xff0c;还想添加一个按钮之类的 GUI Widget, 需要用 Dear Imgui。由于 Imgui 对于2D图形渲染并没有提供类似 SFML 的 API, 结合它们两个使用是一个比较好的方法, 找到了 imgui-SFML 这个…...

Linux-Vim的使用,快速入门Vim,Linux入门教程,精讲Linux

Vim的三种模式 输入模式&#xff0c;键入 i 或 a 或 o 都可以进入输入模式。 普通模式&#xff0c;打开Vim默认的模式。 命令模式&#xff0c;键入 : 进入命令模式。 注意&#xff1a;按下 ESC 可以从输入模式或命令模式退回到普通模式 退出 vim &#xff0c;需要在普通模式下…...

目标检测 | 卷积神经网络(CNN)详细介绍及其原理详解

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;是一种深度学习模型&#xff0c;主要用于图像识别和计算机视觉任务。它的设计灵感来自于生物学中视觉皮层的工作原理。CNN的核心思想是通…...

信步SV1a-13714P嵌入式主板拆解:工业边缘计算硬件选型与实战部署指南

1. 项目概述&#xff1a;一块嵌入式主板的深度拆解最近在整理一个工业边缘计算的项目资料&#xff0c;翻出了几块之前用过的“信步科技SV1a-13714P”嵌入式主板。这块板子虽然不是什么新潮的玩意儿&#xff0c;但在特定的工业场景里&#xff0c;它就像一颗“定心丸”&#xff0…...

从零到一:用面包板和晶体管手搓一个4bit加法器(附完整电路图与避坑指南)

从零到一&#xff1a;用面包板和晶体管手搓一个4bit加法器&#xff08;附完整电路图与避坑指南&#xff09; 深夜的实验室里&#xff0c;面包板上横七竖八地插着几十个三极管和电阻&#xff0c;当我第三次测量到错误的输出电平时&#xff0c;终于意识到——这个看似简单的4bit加…...

【免费下载】 探索双面神技:STM32G474的USB跨界应用

探索双面神技&#xff1a;STM32G474的USB跨界应用 在物联网与嵌入式开发的世界里&#xff0c;寻找一款能兼顾数据传输与控制沟通的神器是每个开发者的心头好。今天&#xff0c;我们就来揭秘这样一个宝藏项目——STM32G474实现USB的MSCCDC组合功能&#xff0c;它巧妙地将STM32G4…...

【亲测免费】 TC8协议一致性测试文档

TC8协议一致性测试文档 【下载地址】TC8协议一致性测试文档 本仓库提供了一个重要的资源文件&#xff0c;即**TC8协议一致性测试文档**。该文档详细描述了汽车以太网ECU&#xff08;电子控制单元&#xff09;在不同网络层的一致性测试规范。具体包括以下三个部分&#xff1a;1.…...

别再只用DS18B20了!用51单片机和ADC0804做个PT100温度计,从硬件接线到代码调试全流程

从DS18B20到PT100&#xff1a;用51单片机打造工业级温度监测系统 在嵌入式开发领域&#xff0c;温度测量是一个永恒的话题。当大多数初学者还停留在使用DS18B20这类数字温度传感器时&#xff0c;工业领域早已广泛采用PT100铂电阻作为温度测量的主力军。本文将带你跨越数字传感器…...

Cadence SPB17.4导入外部封装后,原理图封装属性不更新?一个属性编辑框解决你的困扰

Cadence SPB17.4原理图封装属性更新难题&#xff1a;从数据库到设计的完整解决方案 当你花费数小时将力创封装库成功导入Cadence PCB Editor后&#xff0c;满心欢喜地打开原理图进行DRC检查&#xff0c;却发现那些熟悉的"PCB Footprint Not Found"错误依然存在——这…...

herebedragons完整指南:20+种3D渲染API对比实战

herebedragons完整指南&#xff1a;20种3D渲染API对比实战 【免费下载链接】herebedragons A basic 3D scene implemented with various engines, frameworks or APIs. 项目地址: https://gitcode.com/gh_mirrors/he/herebedragons herebedragons是一个独特的开源项目&a…...

企业自建内部知识库,最容易死在这8个问题上(管理+技术双维度)

很多企业想做内部知识库&#xff1a;把经验、图纸、方案、流程、故障案例沉淀下来&#xff0c;避免人员流失就丢技术、避免重复踩坑。但真正落地后&#xff0c;90%都变成了“僵尸文档库”——要么没人用、没人更&#xff0c;要么技术层面跟不上需求&#xff0c;AI模式形同虚设。…...

别再为调试发愁!FreeRTOS下STM32串口打印的三种实用方案(含USART3重定向避坑)

FreeRTOS下STM32串口调试的三大实战方案与深度优化指南 在嵌入式开发中&#xff0c;调试信息的输出如同黑夜中的灯塔&#xff0c;为开发者指明程序运行的轨迹。当FreeRTOS遇上STM32&#xff0c;串口打印这个看似基础的功能却可能成为项目推进的绊脚石。本文将带您深入探索三种经…...

算力基石:CPU、GPU与嵌入式AI的技术逻辑与融合发展

在人工智能全面普及的时代&#xff0c;算力已经成为数字产业发展的核心驱动力。从日常使用的智能手机、家用电脑&#xff0c;到云端大模型、智能汽车、工业传感设备&#xff0c;各类智能终端的运转都离不开处理器的算力支撑。其中&#xff0c;CPU作为通用计算核心、GPU作为并行…...