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

[Linux网络编程]04-多进程/多线程并发服务器思路分析及实现(进程,信号,socket,线程...)

一.思路

实现一个服务器可以连接多个客户端,每当accept函数等待到客户端进行连接时 就创建一个子进程;
核心思路:让accept循环阻塞等待客户端,每当有客户端连接时就fork子进程,让子进程去和客户端进行通信,父进程用于监听并使用信号捕捉回收子进程;(子进程关闭用于监听的套接字lfd,父进程关闭用于通信的cfd)

二.多进程并发服务器代码实现:

1.利用while 和 accept 阻塞等待客户端连接,一旦有一个客户端连接上,就创建一个新的子进程执行服务逻辑。
2.子进程结束时,利用信号捕捉函数sigaction回收子进程
3.注意,当主进程阻塞在accept时,若子进程发出信号,accept会被打断(一系列慢速系统调用的特点)从而直接执行接下来的fork函数,这就会导致一个子进程刚好被回收后,又会产生一个新的子进程,为了防止这种情况,使用again和goto维护accept,防止被信号打断后产生错误。

  1 #include<iostream>                                                                                        2 #include<unistd.h>3 #include<sys/socket.h>4 #include<arpa/inet.h>5 #include<signal.h>6 #include<sys/wait.h>7 using namespace std;8 9 void huidiao(int signo)10 {11  pid_t pid;12  while((pid = waitpid(-1,NULL,WNOHANG))>0)13  {14    cout<<pid<<endl;15  }16  return ;17 }18 19 int main()20 { 21      struct sigaction act;22      act.sa_handler = huidiao; sigemptyset(&act.sa_mask);24      act.sa_flags = 0;25      sigaction(SIGCHLD,&act,NULL);26   //socket bind listen accept27   int fd = socket(AF_INET,SOCK_STREAM,0);28   struct sockaddr_in serveraddr,clientaddr;29   serveraddr.sin_family = AF_INET;30   serveraddr.sin_port = htons(9876);31   serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);32   bind(fd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));33 34   listen(fd,128);35 36   socklen_t clientaddr_len = sizeof(clientaddr);37   int sfd,flag;38   while(true)39   {40     sfd = accept(fd,(struct sockaddr*)&clientaddr,&clientaddr_len);41     flag = fork();42    43     if(flag == 0)44     {                                      close(fd);46       break;47     }48     else if(flag <0)49     {50       exit(1);51     }52     else if(flag>0) 53     {54       close(sfd);55       continue;56     }57   } 58 59     if(flag == 0)60 {                                                                           61       for(;;)62     {63        char buf[1024];64        int n = read(sfd,buf,sizeof(buf));65        if(n==0)66        {                              close(sfd);68           cout<<"jieshu"<<endl;69           exit(0);70        }71           for(int i = 0;i<n;i++)72           {73             buf[i] = toupper(buf[i]);74           }75           write(STDOUT_FILENO,buf,n);76           write(sfd,buf,n);77     }78 }79  return 0;80 }

三. 多线程并发服务器代码实现:

1.#include <stdio.h>  
2.#include <string.h>  
3.#include <arpa/inet.h>  
4.#include <pthread.h>  
5.#include <ctype.h>  
6.#include <unistd.h>  
7.#include <fcntl.h>  
8.  
9.#include "wrap.h"  
10.  
11.#define MAXLINE 8192  
12.#define SERV_PORT 8000  
13.  
14.struct s_info {                     //定义一个结构体, 将地址结构跟cfd捆绑  
15.    struct sockaddr_in cliaddr;  
16.    int connfd;  
17.};  
18.  
19.void *do_work(void *arg)  
20.{  
21.    int n,i;  
22.    struct s_info *ts = (struct s_info*)arg;  
23.    char buf[MAXLINE];  
24.    char str[INET_ADDRSTRLEN];      //#define INET_ADDRSTRLEN 16  可用"[+d"查看  
25.  
26.    while (1) {  
27.        n = Read(ts->connfd, buf, MAXLINE);                     //读客户端  
28.        if (n == 0) {  
29.            printf("the client %d closed...\n", ts->connfd);  
30.            break;                                              //跳出循环,关闭cfd  
31.        }  
32.        printf("received from %s at PORT %d\n",  
33.                inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),  
34.                ntohs((*ts).cliaddr.sin_port));                 //打印客户端信息(IP/PORT)  
35.  
36.        for (i = 0; i < n; i++)   
37.            buf[i] = toupper(buf[i]);                           //小写-->大写  
38.  
39.        Write(STDOUT_FILENO, buf, n);                           //写出至屏幕  
40.        Write(ts->connfd, buf, n);                              //回写给客户端  
41.    }  
42.    Close(ts->connfd);  
43.  
44.    return (void *)0;  
45.}  
46.  
47.int main(void)  
48.{  
49.    struct sockaddr_in servaddr, cliaddr;  
50.    socklen_t cliaddr_len;  
51.    int listenfd, connfd;  
52.    pthread_t tid;  
53.  
54.    struct s_info ts[256];      //创建结构体数组.  
55.    int i = 0;  
56.  
57.    listenfd = Socket(AF_INET, SOCK_STREAM, 0);                     //创建一个socket, 得到lfd  
58.  
59.    bzero(&servaddr, sizeof(servaddr));                             //地址结构清零  
60.    servaddr.sin_family = AF_INET;  
61.    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);                               //指定本地任意IP  
62.    servaddr.sin_port = htons(SERV_PORT);                                       //指定端口号   
63.  
64.    Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));             //绑定  
65.  
66.    Listen(listenfd, 128);                                                      //设置同一时刻链接服务器上限数  
67.  
68.    printf("Accepting client connect ...\n");  
69.  
70.    while (1) {  
71.        cliaddr_len = sizeof(cliaddr);  
72.        connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);   //阻塞监听客户端链接请求  
73.        ts[i].cliaddr = cliaddr;  
74.        ts[i].connfd = connfd;  
75.  
76.        pthread_create(&tid, NULL, do_work, (void*)&ts[i]);  
77.        pthread_detach(tid);                                                    //子线程分离,防止僵线程产生.  
78.        i++;  
79.    }  
80.  
81.    return 0;  
82.}  

相关文章:

[Linux网络编程]04-多进程/多线程并发服务器思路分析及实现(进程,信号,socket,线程...)

一.思路 实现一个服务器可以连接多个客户端&#xff0c;每当accept函数等待到客户端进行连接时 就创建一个子进程; 核心思路&#xff1a;让accept循环阻塞等待客户端&#xff0c;每当有客户端连接时就fork子进程&#xff0c;让子进程去和客户端进行通信&#xff0c;父进程用于…...

《OpenCV计算机视觉》—— 年龄与性别预测

结合以下链接中的文章有助于理解此篇案例&#xff1a; OpenCV中的 cnn 模块 https://blog.csdn.net/weixin_73504499/article/details/142965441?spm1001.2014.3001.5501 此案例是通过使用OpenCV中的cnn模块来调用别人已经训练好的深度学习模型&#xff0c;此篇案例中用到了…...

详解23种设计模式——第一部分:概述+创建型模式

目录 1. 概述 2. 创建型模式 2.1 简单&#xff08;静态&#xff09;工厂模式 2.1.1 介绍 2.1.2 实现 2.2 工厂模式 2.3 抽象工厂模式 2.4 单例模式 2.4.1 饿汉模式 2.4.2 懒汉模式 2.4.3 线程安全的懒汉式 2.4.4 DCL单例 - 高性能的懒汉式 2.5 建造者模式 2.6 原…...

semi-Naive Bayesian(半朴素贝叶斯)

semi-Naive Bayesian&#xff08;半朴素贝叶斯&#xff09; 引言 朴素贝叶斯算法是基于特征是相互独立这个假设开展的&#xff08;为了降低贝叶斯公式: P ( c ∣ x ) P ( c ) P ( x ∣ c ) P ( x ) P(c|x) \frac {P(c)P(x|c)}{P(x)} P(c∣x)P(x)P(c)P(x∣c)​中后验概率 P …...

大语言模型(LLM)入门级选手初学教程

链接&#xff1a;https://llmbook-zh.github.io/ 前言&#xff1a; GPT发展&#xff1a;GPT-1 2018 -->GPT-2&GPT-3&#xff08;扩大预训练数据和模型参数规模&#xff09;–> GPT-3.5&#xff08;代码训练、人类对齐、工具使用等&#xff09;–> 2022.11 ChatG…...

HTML 实例/测验之HTML 基础一口气讲完!(o-ωq)).oO 困

HTML 基础 非常简单的HTML文档 <!DOCTYPE html> <html><head><title>页面标题(w3cschool.cn)</title></head><body><h1>我的第一个标题</h1><p>我的第一个段落。</p></body> </html> 输出&a…...

c语言基础程序——经典100道实例。

c语言基础程序——经典100道实例 001&#xff0c; 组无重复数字的数002&#xff0c;企业发放的奖金根据利润提成003&#xff0c;完全平方数004&#xff0c;判断当天是这一年的第几天005&#xff0c;三个数由小到大输出006&#xff0c;输出字母C图案007&#xff0c;特殊图案008&…...

火星求生CE修改金钱,无限资金

由于火星求生前期没有资金非常难玩&#xff0c;想通过修改资金渡过前期&#xff0c;网上找了一圈修改器&#xff0c;只有修改无限声望和无限科研&#xff0c;就是没有无限资金&#xff0c;于是自己用CE修改 教程 首先查看自己资金是多少M&#xff0c;如下图我是22430M资金&…...

linux 内存管理-slab分配器

伙伴系统用于分配以page为单位的内存,在实际中很多内存需求是以Byte为单位的,如果需要分配以Byte为单位的小内存块时,该如何分配呢? slab分配器就是用来解决小内存块分配问题,也是内存分配中非常重要的角色之一。 slab分配器最终还是由伙伴系统分配出实际的物理内存,只不过s…...

docker-compose部署gitlab(亲测有效)

一.通过DockerHub拉取Gitlab镜像 docker pull gitlab/gitlab-ce:latest 二.创建目录 mkdir -p /root/tool/gitlab/{data,logs,config} && cd /root/tool/gitlab/ 三.编辑DockerCompose.yaml文件 vim /root/tool/gitlab/docker-compose.yml version: "3&quo…...

Leetcode 赎金信

利用hash map做 java solution class Solution {public boolean canConstruct(String ransomNote, String magazine) {//首先利用HashMap统计magazine中字符频率HashMap<Character, Integer> magazinefreq new HashMap<>();for(char c : magazine.toCharArray())…...

S7--环境搭建基本操作

1.修改蓝牙名称和地址 工程路径:$ADK_ROOT\adk\src\filesystems\CDA2\factory_default_config\ 在subsys7_config5.htf中 DeviceName = "DEVICE_NAME“ # replace with your device name BD_ADDRESS=[00 FF 00 5B 02 00] # replace with your BD address 2.earbud工程修改…...

webAPI中的排他思想、自定义属性操作、节点操作(配大量案例练习)

一、排他操作 1.排他思想 如果有同一组元素&#xff0c;我们想要某一个元素实现某种样式&#xff0c;需要用到循环的排他思想算法&#xff1a; 1.所有的元素全部清除样式 2.给当前的元素设置样式 注意顺序能不能颠倒&#xff0c;首先清除全部样式&#xff0c;再设置自己当前的…...

101、QT摄像头录制视频问题

视频和音频录制类QMediaRecorder QMediaRecorder 通过摄像头和音频输入设备进行录像。 注意: 使用Qt多媒体模块的摄像头相关类无法在Windows平台上进行视频录制&#xff0c;只能进行静态图片抓取但是在Linux平台上可以实现静态图片抓取和视频录制。 Qt多媒体模块的功能实现是依…...

FairGuard游戏加固全面适配纯血鸿蒙NEXT

2024年10月8日&#xff0c;华为正式宣布其原生鸿蒙操作系统 HarmonyOS NEXT 进入公测阶段&#xff0c;标志着其自有生态构建的重要里程碑。 作为游戏安全领域领先的第三方服务商&#xff0c;FairGuard游戏加固在早期就加入了鸿蒙生态的开发&#xff0c;基于多项独家技术与十余年…...

鲸信私有化即时通信如何平衡安全性与易用性之间的关系?

即时通信已经成为我们生活中不可或缺的一部分。从日常沟通到工作协作&#xff0c;每一个信息的传递都承载着信任与效率。然而&#xff0c;随着网络安全威胁日益严峻&#xff0c;如何在享受即时通信便捷的同时&#xff0c;确保信息的私密性与安全性&#xff0c;成为了摆在我们面…...

vivado 接口带宽验证

存储器接口 使用赛灵思存储器 IP 时需要更多的 I/O 管脚分配步骤。自定义 IP 之后&#xff0c;您可采用 Vivado IDE 中的细化 (elaborated) 或综 合 (synthesized) 设计分配顶层 IP 端口到物理封装引脚。同每一个存储器 IP 关联的所有端口都被纳入一个 I/O 端口接口…...

Qt中使用线程之QThread

使用Qt中自带的线程类QThread时 1、需要定义一个子类继承自QThread 2、重写run()方法&#xff0c;在run方法中编写业务逻辑 3、子类支持信号槽 4、子类的构造函数的执行是在主线程进行的&#xff0c;而run方法的执行是在子线程中进行的 常用方法 静态方法 获取线程id 可…...

多IP连接

一.关闭防火墙 systemctl stop firewalld setenforce 0 二.挂在mnt mount /dev/sr0 /mnt 三.下载nginx dnf install nginx -y 四.启动nginx协议 systemctl start nginx 五.修改协议 vim /etc/nginx/nginx.conf 在root前加#并且下一行添加 root /www:&#xff08;浏…...

Linux重点yum源配置

1.配置在线源 2.配置本地源 3.安装软件包 4.测试yum源配置 5.卸载软件包...

289.生命游戏

目录 题目解法代码说明&#xff1a; 每一个各自去搜寻他周围的信息&#xff0c;肯定存在冗余&#xff0c;如何优化这个过程&#xff1f;如何遍历每一个元素的邻域&#xff1f;方向数组如何表示方向&#xff1f; auto dir : directions这是什么用法board[i][j]一共有几种状态&am…...

如何保证Redis和数据库的数据一致性

文章目录 0. 前言1. 补充知识&#xff1a;CP和AP2. 什么情况下会出现Redis与数据库数据不一致3. 更新缓存还是删除缓存4. 先操作缓存还是先操作数据库4.1 先操作缓存4.1.1 数据不一致的问题是如何产生的4.1.2 解决方法&#xff08;延迟双删&#xff09;4.1.3 最终一致性和强一致…...

Android Framework AMS(06)startActivity分析-3(补充:onPause和onStop相关流程解读)

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要解读AMS通过startActivity启动Activity的整个流程的补充&#xff0c;更新了startActivity流程分析部分。 一般来说&#xff0c;有Activ…...

【LangChain系列2】【Model I/O详解】

目录 前言一、LangChain1-1、介绍1-2、LangChain抽象出来的核心模块1-3、特点1-4、langchain解决的一些行业痛点1-5、安装 二、Model I/O模块2-0、Model I/O模块概要2-1、Format&#xff08;Prompts Template&#xff09;2-1-1、Few-shot prompt templates2-1-2、Chat模型的少样…...

动态规划-子数组系列——1567.乘积为正数的最长子数组

1.题目解析 题目来源&#xff1a;1567.乘积为正数的最长子数组——力扣 测试用例 2.算法原理 1.状态表示 因为数组中存在正数与负数&#xff0c;如果求乘积为正数的最长子数组&#xff0c;那么存在两种情况使得乘积为正数&#xff0c;第一种就是正数乘以正数&#xff0c;第…...

Linux 运行执行文件并将日志输出保存到文本文件中

在 Linux 系统中运行可执行文件并将日志输出保存到文本文件中&#xff0c;可以使用以下几种方法&#xff1a; 方法一&#xff1a;使用重定向符号 > 或 >> 覆盖写入&#xff08;>&#xff09;&#xff1a; ./your_executable > logfile.txt这会将可执行文件的输…...

注册安全分析报告:北外网校

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…...

预警期刊命运逆袭到毕业好刊,仅45天!闭眼冲速度,发文量暴增!

选刊发表不迷路&#xff0c;就找科检易学术 期刊官网&#xff1a;Sustainability | An Open Access Journal from MDPI 1、期刊信息 期刊简介&#xff1a; Sustainability 是一本国际性的、同行评审的开放获取期刊&#xff0c;由MDPI出版社每半月在线出版。该期刊专注于人类…...

【LeetCode每日一题】——523.连续的子数组和

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 前缀和 二【题目难度】 中等 三【题目编号】 523.连续的子数组和 四【题目描述】 给你一个…...

leetcode54:螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1a;matrix [[1,2,3,…...