实现多线程并发服务器和多进程并发服务器(Linux网络编程)

多进程并发服务器

实现流程

	1. Socket();		创建 监听套接字 lfd2. Bind()	绑定地址结构 Strcut scokaddr_in addr;3. Listen();	4. while (1) {cfd = Accpet();			接收客户端连接请求。pid = fork();if (pid == 0){			子进程 read(cfd) --- 小写->大写 --write(cfd)			close(lfd)		关闭用于建立连接的套接字 lfdread()//小写转大写代码write()} else if (pid > 0{	close(cfd);		关闭用于与客户端通信的套接字 cfd	continue;}}5. 子进程:close(lfd)read()小写->大写write()	父进程:close(cfd);注册信号捕捉函数:	SIGCHLD在回调函数中, 完成子进程回收whilewaitpid();read 函数的返回值:1. > 0 实际读到的字节数2. = 0 已经读到结尾(对端已经关闭)【 !重 !点 !】3. -1 应进一步判断errno的值:errno = EAGAIN or EWOULDBLOCK: 设置了非阻塞方式 读。 没有数据到达。 errno = EINTR 慢速系统调用被 中断。errno = “其他情况” 异常。

代码

#include <stdio.h>  
#include <ctype.h>  
#include <stdlib.h>  
#include <sys/wait.h>  
#include <string.h>  
#include <strings.h>  
#include <unistd.h>  
#include <errno.h>  
#include <signal.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <pthread.h>  #include "wrap.h"  #define SRV_PORT 9999  void catch_child(int signum)  
{  while ((waitpid(0, NULL, WNOHANG)) > 0);  return ;  
}  int main(int argc, char *argv[])  
{  int lfd, cfd;  pid_t pid;  struct sockaddr_in srv_addr, clt_addr;  socklen_t clt_addr_len;   char buf[BUFSIZ];  int ret, i;  //memset(&srv_addr, 0, sizeof(srv_addr));                 // 将地址结构清零  bzero(&srv_addr, sizeof(srv_addr));  srv_addr.sin_family = AF_INET;  srv_addr.sin_port = htons(SRV_PORT);  srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  lfd = Socket(AF_INET, SOCK_STREAM, 0);  Bind(lfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));  Listen(lfd, 128);  clt_addr_len = sizeof(clt_addr);  while (1) {  cfd = Accept(lfd, (struct sockaddr *)&clt_addr, &clt_addr_len);  pid = fork();  if (pid < 0) {  perr_exit("fork error");  } else if (pid == 0) {  close(lfd);  break;          } else {  struct sigaction act;  act.sa_handler = catch_child;  sigemptyset(&act.sa_mask);  act.sa_flags = 0;  ret = sigaction(SIGCHLD, &act, NULL);  if (ret != 0) {  perr_exit("sigaction error");  }  close(cfd);   continue;  }  }  if (pid == 0) {  for (;;) {  ret = Read(cfd, buf, sizeof(buf));  if (ret == 0) {  close(cfd);  exit(1);  }   for (i = 0; i < ret; i++)  buf[i] = toupper(buf[i]);  write(cfd, buf, ret);  write(STDOUT_FILENO, buf, ret);  }  }  return 0;  
}  

多线程并发服务器

实现流程

1. Socket();		创建 监听套接字 lfd2. Bind()		绑定地址结构 Strcut scokaddr_in addr;3. Listen();		4. while (1) {		cfd = Accept(lfd, );pthread_create(&tid, NULL, tfn, (void *)cfd);pthread_detach(tid);  				// pthead_join(tid, void **);  新线程---专用于回收子线程。}5. 子线程:void *tfn(void *arg) {// close(lfd)			不能关闭。 主线程要使用lfdread(cfd)--write(cfd)pthread_exit((void *)10;	}

代码

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/4897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pytest测试之conftest详解

一、概述   Conftest是一个Python测试框架&#xff0c;它是pytest的一个组件&#xff0c;用于配置测试环境和参数。通过Conftest&#xff0c;我们可以创建一个可复用的测试配置文件&#xff0c;以便在多个测试模块之间共享配置信息。Conftest非常适合用于管理大型项目中的测试…

scrollintoview方法滚动距离顶部距离

scrollIntoView 方法是 DOM API 的一部分&#xff0c;用于将元素滚动到视图中。这个方法接收一个布尔值参数 alignToTop&#xff0c;指示是否需要滚动到视图的顶部。 以下是如何使用 scrollIntoView 方法的示例代码&#xff1a; // 获取需要滚动的元素 const element docume…

机器学习-11-卷积神经网络-基于paddle实现神经网络

文章目录 总结参考本门课程的目标机器学习定义第一步&#xff1a;数据准备第二步&#xff1a;定义网络第三步&#xff1a;训练网络第四步&#xff1a;测试训练好的网络 总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍基于paddle实现神经网络。 参考 MNIST 训练_副…

编译Qt6.5.3LTS版本(Mac/Windows)的mysql驱动(附带编译后的全部文件)

文章目录 0 背景1 编译过程2 福利参考 0 背景 因为项目要用到对MYSQL数据库操作&#xff0c;所以需要连接到MYSQL数据库。但是连接需要MYSQL驱动&#xff0c;但是Qt本身不自带MYSQL驱动&#xff0c;需要自行编译。网上有很多qt之前版本的mysql驱动&#xff0c;但是没有找到qt6…

使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B

2024年4月18日&#xff0c;meta开源了Llama 3大模型[1]&#xff0c;虽然只有8B[2]和70B[3]两个版本&#xff0c;但Llama 3表现出来的强大能力还是让AI大模型界为之震撼了一番&#xff0c;本人亲测Llama3-70B版本的推理能力十分接近于OpenAI的GPT-4[4]&#xff0c;何况还有一个4…

降薪、调岗、裁员,库迪咖啡没有“钱景”

文 | 螳螂观察 作者 | 青玥 2024年&#xff0c;连锁咖啡行业依然激战正酣。 卷价格、卷联名、卷代言人&#xff0c;部分咖啡小店已经在这样内卷的氛围中&#xff0c;率先被淘汰&#xff0c;咖门的统计数据显示&#xff0c;2023年前九个月&#xff0c;注销的咖啡企业有9825家…

Unity 数字字符串逗号千分位

使用InputField时处理输入的数字型字符串千分位自动添加逗号&#xff0c;且自动保留两位有效数字 输入&#xff1a;123 输出&#xff1a;123.00 输入&#xff1a;12345 输出&#xff1a;12,345.00 代码非常简单 using UnityEngine; using TMPro;public class …

前端高并发的出现场景及解决方法——技能提升——p-limit的使用

最近在写后台管理系统的时候&#xff0c;遇到一个场景&#xff0c;就是打印的页面需要根据传入的多个id&#xff0c;分别去请求详情接口。 比如id有10个&#xff0c;则需要调用10次详情接口获取到数据&#xff0c;最后对所有的数据进行整合后页面渲染。 相信大家或多或少都遇到…

redis中使用pipeline批量执行命令,提升性能

注意&#xff1a;此操作非原子性 将一批要执行的redis命令提交到pipeline中&#xff0c;pipeline一次性的将数据发送给服务器&#xff0c;服务器再逐条执行命令。 redisTemplate中已经提供了对应方法executePipelined()可以直接调用&#xff0c;它支持两个类型…

ASP.NET实验室预约系统的设计

摘 要 实验室预约系统的设计主要是基于B/S模型&#xff0c;在Windows系统下&#xff0c;运用ASP.NET平台和SQLServer2000数据库实现实验室预约功能。该设计主要实现了实验室的预约和管理功能。预约功能包括老师对实验室信息、实验项目和实验预约情况的查询以及对实验室的预约…

Linux--05---相对路径与绝对路径、终端的认识

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. 相对路径与绝对路径切换到用户家目录&#xff1a;cd ~当前目录&#xff1a;./ 2. 对终端的认识3. 文件的类型颜色表示的文件类型&#xff1a;文件类型和权限的表…

基于深度学习的实时人脸检测与情绪分类

情绪分类 实时人脸检测与情绪分类 Kaggle Competion 数据集 fer2013 中的测试准确率为 66%CK数据集的检验准确率为99.87%情绪分类器模型预测从网络摄像头捕获的实时视频中的平均成本时间为 4~ 10ms 关键技术要点&#xff1a; 实时人脸检测&#xff1a;系统采用了前沿的人脸检…

sql将日期区间拆分为多行

将日期区间拆分为多行 将二维表格中的开始时间结束间用sql拆分成多行连续的时间 源数据 start_dateend_date2023-12-012023-12-03 结果 biz_datestart_dateend_date2023-01-012023-12-012023-12-032023-01-022023-12-012023-12-032023-01-032023-12-012023-12-03 代码 S…

明日周刊-第8期

现在露营的人越来越多了&#xff0c;都是带着帐篷或者遮阳篷聚在一起喝喝茶聊聊天&#xff0c;这是一种很好的放松方式。最近我养了一只金毛&#xff0c;目前两个月大&#xff0c;非常可爱。 文章目录 一周热点资源分享言论歌曲推荐 一周热点 一、人工智能领域 本周&#xff…

迈威通信首秀成都工博会,迸发品牌强势能

4月26日&#xff0c;在繁花似锦的成都&#xff0c;一场工业界的盛会刚刚落下帷幕。而在这场盛会的璀璨星辰中&#xff0c;迈威通信以其首秀之姿&#xff0c;迸发出耀眼的光芒&#xff0c;强势展现了品牌的实力与魅力。 此次展会&#xff0c;迈威通信以“工业互联赋能新数字化智…

武汉大学计算机复试经验贴(完善版)

一、复试考察内容及比例 1、上机测试&#xff0c;40% 2、口语测试&#xff0c;20% 3、综合面试&#xff0c;40% 二、上机测试 1、考察形式&#xff1a; 时长120分钟&#xff0c;5道题目&#xff0c;编译环境是DevCpp&#xff0c;题目难度比PAT乙级略低&#xff0c;人工打分…

Go 语言函数

函数是基本的代码块&#xff0c;用于执行一个任务。 Go 语言最少有个 main() 函数。 你可以通过函数来划分不同功能&#xff0c;逻辑上每个函数执行的是指定的任务。 函数声明告诉了编译器函数的名称&#xff0c;返回类型&#xff0c;和参数。 Go 语言标准库提供了多种可动…

C语言求 MD5 值

MD5值常被用于验证数据的完整性&#xff0c;嵌入式开发时经常用到。md5sum命令可以求MD5码&#xff0c;下面介绍如何用C语言实现MD5功能。 一、求字符串MD5值 1、md5sum命令 $ echo -n "12345678" | md5sum //获取"12345678"字符串的md5值 结果&…

偏测试技术面试,高频面试题分享

一.介绍下你们公司产品的后端模块? 以电商微服务架构示例&#xff1a; 用户服务 (User Service)&#xff1a; 负责用户注册、登录、个人信息管理等功能。存储用户数据&#xff0c;如用户名、密码、个人资料等。商品服务 (Product Service)&#xff1a; 管理商品信息&#xf…

2023 网络工程师软考-真题解析(1)

在某台主机上无法访问域名为wwww.aaa.cn 的网站&#xff0c;而局域网中的其他主机可正常访问&#xff0c;在该主机上执行ping命令时有如下所示的信息: C:\>ping www.aaa.cn Pinging www.aaa.cn [202.114.10.56lwith 32 bytes of data. Reply from 202.114.10.56:Destinat…