简单实现多进程和多线程的并发服务器

多线程并发服务器的实现 attr:线程的的属性,一般置为NULL,表示默认属性;创建线程,对通信模块的调用。第三个是回掉函数,线程所要执行的功能;4.通信模块:read函数将读取的数据保存在数组中。第四个是回掉函数的参数;5.主函数:调用函数完成套接字的创建等基本步骤。无阻塞回收结束的子进程的函数。1.多线程服务器的实现是在多进程服务器的基础上增改了一些功能。阻塞回收结束的子进程的函数。1.套接字的创建,ip地址初始化。参数说明:thread:线程号。 阅读详情

多进程版本的并发服务器

//多进程版本的网络服务器
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<ctype.h>
#include<signal.h>
#include"wrap.h"
#include<sys/wait.h>


//信号处理函数
void waitchild(int signo){

	pid_t wpid;
	//情况:在SIGCHLD执行期间,另外的2个以上的进程同时退出,此时会出现僵尸进程
	//循环回收子进程,
	//当waitpid==-1时表示已经回收所有子进程
	while(1){

		wpid = waitpid(-1 , NULL , WNOHANG);
		if(wpid>0){

			printf("child exit , wpid==[%d]\n", wpid);
		}
		else if(wpid==0 || wpid==-1){

			break;
		}
	}

}
int main()
{
	//创建socket
	

	int lfd=Socket(AF_INET,SOCK_STREAM,0);


	//设置端口复用 
	//解决"bind Address already in use "
	int opt = 1;
	int ret=setsockopt(lfd, SOL_SOCKET ,SO_REUSEADDR, &opt ,sizeof(int));
	if(ret==-1){

		printf("sockopt");
		exit(1);
	}
	//绑定
	struct sockaddr_in serv;
	bzero(&serv,sizeof(serv));
	serv.sin_family=AF_INET;
	serv.sin_addr.s_addr=htonl(INADDR_ANY);
	serv.sin_port = htons(8888);
	Bind(lfd,(struct sockaddr *)&serv, sizeof(serv));

	//设置监听
	listen(lfd,128);


	//阻塞SIGCHLD信号
	//防止情况发生:还未完成信号处理函数的注册,子进程都推出了
	sigset_t mask;
	sigemptyset(&mask);
	sigaddset(&mask , SIGCHLD);
	sigprocmask(SIG_BLOCK, &mask ,NULL);


	pid_t pid;
	int cfd;
	char sIP[16];
	socklen_t len;
	struct sockaddr_in client;

	while(1){

		//等待客户端连接
		memset(sIP , 0x00, sizeof(sIP));
		len = sizeof(client);

		cfd=Accept(lfd, (struct sockaddr *)&client , &len);
		printf("client-->[%s]:[%d]\n",inet_ntop(AF_INET, &client.sin_addr.s_addr ,sIP, sizeof(sIP)), ntohs(client.sin_port));

		pid = fork();
		if(pid<0){

			perror("fork error\n");
			exit(-1);

		}
		else if(pid>0){

			//关闭通信文件描述符
			close(cfd);

			//注册SIGCHLD信号处理函数
			//sa_handler:指定信号捕捉后的处理函数名
			//sa_mask:用来指定在信号处理函数执行期间所要屏蔽(阻塞)的信号
			struct sigaction act;
			act.sa_handler = waitchild;
			act.sa_flags = 0;
			sigemptyset(&act.sa_mask);   //清空信号集
			sigaction(SIGCHLD , &act , NULL);

			//解除对SIGCHLD信号的阻塞
			sigprocmask(SIG_UNBLOCK , &mask , NULL);
		}
		else if(pid==0){

			//关闭监听文件描述符
			close(lfd);

			//读数据
			int n;
			char buf[1024];

			while(1){

				n=Read(cfd, buf ,sizeof(buf));
			
				if(n<=0){

				printf("read error or client closed,n=[%d]\n",n);
				break;
				}

				for(int i=0;i<n;++i){

					buf[i] = toupper(buf[i]);
				}
			//发送数据
				Write( cfd, buf, n );
			}
		
		}
			
		//关闭cfd;
		
		close(cfd);
		exit(0);

	}

	close(lfd);
	return 0;
}

注意情况发生:
1.还未完成信号处理函数的注册,子进程都退出的问题
2.端口复用问题

改进
//信号处理函数
void waitchild(int signo){

	pid_t wpid;
	//情况:在SIGCHLD执行期间,另外的2个以上的进程同时退出,此时会出现僵尸进程
	//循环回收子进程,
	//当waitpid==-1时表示已经回收所有子进程
	while(1){

		wpid = waitpid(-1 , NULL , WNOHANG);
		if(wpid>0){

			printf("child exit , wpid==[%d]\n", wpid);
		}
		else if(wpid==0 || wpid==-1){

			break;
		}
	}

}
int main()
{
	//创建socket
	

	int lfd=Socket(AF_INET,SOCK_STREAM,0);

	//绑定
	struct sockaddr_in serv;
	bzero(&serv,sizeof(serv));
	serv.sin_family=AF_INET;
	serv.sin_addr.s_addr=htonl(INADDR_ANY);
	serv.sin_port = htons(8888);
	Bind(lfd,(struct sockaddr *)&serv, sizeof(serv));

	//设置监听
	listen(lfd,128);


	//阻塞SIGCHLD信号
	//防止情况发生:还未完成信号处理函数的注册,子进程都推出了
	sigset_t mask;
	sigemptyset(&mask);
	sigaddset(&mask , SIGCHLD);
	sigprocmask(SIG_BLOCK, &mask ,NULL);


	pid_t pid;
	int cfd;
	char sIP[16];
	socklen_t len;
	struct sockaddr_in client;

	while(1){

		//等待客户端连接
		memset(sIP , 0x00, sizeof(sIP));
		len = sizeof(client);

		cfd=Accept(lfd, (struct sockaddr *)&client , &len);
		printf("client-->[%s]:[%d]\n",inet_ntop(AF_INET, &client.sin_addr.s_addr ,sIP, sizeof(sIP)), ntohs(client.sin_port));

		pid = fork();
		if(pid<0){

			perror("fork error\n");
			exit(-1);

		}
		else if(pid>0){

			//关闭通信文件描述符
			close(cfd);

		}
		else if(pid==0){

			//关闭监听文件描述符
			close(lfd);

			//读数据
			int n;
			char buf[1024];

			while(1){

				n=Read(cfd, buf ,sizeof(buf));
			
				if(n<=0){

				printf("read error or client closed,n=[%d]\n",n);
				break;
				}

				for(int i=0;i<n;++i){

					buf[i] = toupper(buf[i]);
				}
			//发送数据
				Write( cfd, buf, n );
			}
		
		}
			
		//关闭cfd;
		
		close(cfd);
		exit(0);

	}

	close(lfd);
	return 0;
}

多线程版本的高并发服务器

void *do_work(void *arg)
{
	
	int cfd=*(int *)arg;

	int n;
	char buf[1024];

	while(1){

		//read数据
		memset(buf, 0x00, sizeof(buf));

		n=Read(cfd , buf ,sizeof(buf));

		if(n<=0){

			printf("read error or client closed,n=[%d]\n",n);
			break;
		}
		printf("n==[%d],buf==[%s]\n",n,buf);

		for(int i=0;i<n;++i){

			buf[i]=toupper(buf[i]);
		}

		//发送数据给客户端
		Write(cfd, buf ,n);

	}

	//关闭通信文件描述符
	close(cfd);

}

int main()
{
	//创建socket
	int lfd = Socket(AF_INET, SOCK_STREAM, 0);

	//bind
	struct sockaddr_in serv;
	bzero(&serv,sizeof(serv));
	serv.sin_family = AF_INET;
	serv.sin_addr.s_addr = htonl(INADDR_ANY);
	serv.sin_port = htons(8888);

	bind(lfd, (struct sockaddr *)&serv , sizeof(serv));

	//监听
	Listen(lfd , 128);


	int cfd;
	pthread_t thread;
	while(1){

		//接受新的连接
		cfd = Accept(lfd ,NULL ,NULL);

		//创建线程
		pthread_create(&thread,NULL,&do_work,&cfd);


		//分离属性
		pthread_detach(thread);
	}

	//关闭监听文件描述符
	close(lfd);

	return 0;

}
多进程/多线程实现服务器的并发 上一节提到的 TCP Socket 调用流程是最简单、最基本的,它基本只能一对一通信,因为使用的是同步阻塞的方式,当服务端在还没处理完一个客户端的网络 I/O 时,或者 读写操作发生阻塞时,其他客户端是无法与服务端连接的。本节我们讲讲最简单的两种方式,使用多线程和多进程实现服务器的并发。 阅读详情

相关推荐

从0实现基于Linux socket聊天室-多线程服务器模型(一)

多线程、多进程模型主要特点是每个网络请求由一个进程/线程处理,线程内部使用阻塞式系统调用,在线程的职能划分上,可以由一个单独的线程处理accept连接,其余线程处理具体的网络请求(收包,处理,发包);单线进程循环原理就是主进程没和客户端通信,客户端都要先连接服务器,服务器接受一个客户端连接后从客户端读取数据,然后处理并将处理的结果返还给客户端,然后再接受下一个客户端的连接请求。1、线程内部还是阻塞的,举个极端的例子,如果一个线程在handle的业务逻辑中sleep了,这个线程也就挂住了。

嵌入式技术开发 1040

91-Linux_多进程/多线程处理服务器并发

多进程/多线程处理服务器并发是为了解决recv阻塞问题;没有多线程多进程处理服务器并发时,只能有一个客户端与其进行通信,当有第二个连接服务器时,就会阻塞在recv阶段,所以引入多进程/多线程处理服务器并发就是为了解决recv的阻塞;

Eccentric哈哈的博客 542

CARLA 0.9.15从零开始:环境搭建与基础场景实战指南

本文是CARLA 0.9.15从零开始的完整环境搭建与基础运行教程。详细介绍了在Linux系统下配置Python环境、下载安装CARLA核心软件包、启动服务器以及运行第一个基础场景的步骤。重点演示了如何通过Python客户端脚本生成随机车流,并手动控制EGO车辆在仿真城市中行驶,为自动驾驶算法开发构建了坚实的仿真测试基础。

weixin_29053383的博客 777

多进程和多线程并发服务器编程模型

  在网络程序里面,一般来说都是许多客户对应一个服务器(多对一),为了处理客户的请求,对服务端的程序就提出了特殊的要求。目前最常用的服务器模型有: 迭代服务器:服务器在同一时刻只能响应一个客户端的请求; 并发服务器:服务器在同一时刻可以响应多个客户端的请求。 一、多进程并发服务器的概念   在 Linux 环境下多进程的应用很多,其中最主要的就是网络/客户服务器。多进程服务器是当客户有请求时,...

青萍之末的博客 1992

41页PPT | 华为业务流程架构全景视图:全业务域L1-L3级流程全案

TBD、收集和生成线索、验证机会点、TBD、管理销售授权、管理销售项目、管理销售项目群、管理合同要素/模板、验证和分发线索、标前引导、管理开票和回款、客户网络评估、管理销售评审、TBD、管理交付项目群、管理合同文档、管理结构化合同信息、跟踪和培育线索、制定并提交标书、管理合同/PO变更、客户网络规划、管理销售决策。:4.1 管理技术、服务请求、4.2管理备件、服务交付、4.3管理非技术、服务请求、4.4管理客户、投诉。:管理Idea、产生Idea、激发兴趣与协作、孵化、原型和验证、确认Idea与商业化。

zuoan1993的博客 4547

AUTOSAR FEE 换页机制深度解析:从原理到实现逻辑

​​没有磨损均衡的EEPROM模拟,如同在沙地上建造城堡​​ ——AUTOSAR存储系统设计箴言

汽车电子软件领域知识分享 1336

多进程多线程总结

1、进程和线程的区别? (1)进程是计算机系统进行资源配置和调度的基本单位,线程是计算机系统执行的最小单位 (2)进程是一个独立的运行单位,他可以看做一个程序或一个应用,而线程是进程的一个执行任务 (3)进程可以包含一个或多个线程,同一进程里面的线程共享数据资源,但是各个线程有自己的栈空间,拥有独立的执行序列。 (4)从逻辑的角度看,多线程的意义在于一个应用程序中,有多个止呕性部分可以同时

九妖的博客 668

AI报告撰写实战指南:从提示词工程到全流程优化的底层逻辑与实践突破

传统AI写作常被诟病为“信息拼贴”——模型虽能生成文本,却常出现逻辑断裂、数据矛盾、风格不符等问题。而“全流程优化”则是通过系统化设计,将报告生成拆解为需求解析→数据对齐→提示词设计→初稿生成→迭代优化→格式适配六大环节,每个环节均通过技术手段提升输出质量。提示词工程:本质是通过结构化指令(如角色设定、任务分解、格式约束、示例引导)精准控制模型输出方向,是连接用户需求与模型能力的“翻译器”。全流程优化。

2501_92808811的博客 884

Linux网络编程【三】:TCP服务器多进程和多线程(http访问)版本

为了让服务器同时接受多个客户端访问,所以需要多进程或者多线程 多进程版本: #include #include #include #include #include #include #include #include static void usage(const char* proc) { printf("%s [ip] [port]", proc); } int startup(c

Begin 1211

工业级以太网通信实战:用FPGA驱动YT8531 PHY芯片的完整避坑指南

本文是一份针对工业级以太网通信的实战指南,详细讲解了如何使用FPGA驱动YT8531 PHY芯片。内容涵盖从硬件设计(电源、时钟、复位)到MDIO接口驱动开发、PHY配置与链路管理的全流程,并重点剖析了十个常见的开发“陷阱”及其解决方案,旨在帮助工程师在复杂的工业环境中实现稳定可靠的以太网通信连接。

weixin_29191669的博客 140

FineBI制作数据可视化大屏-数据连接(1)

快速上手大屏可视化,FineBI数据连接配置。

Pangaoyang_的博客 1909

服务器模型:循环服务器(TCP)和并发服务器(TCP)

服务器模型:循环服务器(TCP)和并发服务器(TCP)搭建

weixin_57723364的博客 2211

手把手教你学Simulink——AC-DC整流器场景:基于传统晶闸管控制整流拓扑的建模:带反电动势负载的单相可控整流器输出特性仿真

在工业电力电子应用中,单相可控整流器常用于将交流电源转换为可调直流电压。当该整流器连接到具有**反电动势(Back EMF)**的负载时(如直流电机、电池充电系统等),其输出特性和工作原理与纯电阻性负载有所不同。本文将带你使用搭建一个带反电动势负载的单相全控桥式整流器模型,并通过仿真分析其输出电压、电流波形以及触发角对输出特性的影响。本文详细介绍了如何使用Simulink搭建一个带反电动势负载的单相全控桥式晶闸管整流器模型,并进行了输出特性的仿真分析。

MHD0815的博客 231

05_TCP并发服务器

05_TCP并发服务器

buhuidage的博客 1331

【AI智能体】Codex 高级进阶使用技巧项目实战操作详解

Codex 高级进阶使用技巧项目实战操作详解

congge 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

简单web服务器

昨天看了一下boa的源码,简单的浏览了一遍,boa是非常优秀的嵌入式web服务器,虽然只支持单任务,但它的高效是其他web服务器不能比拟的,正好这段时间在学习socket编程,那么动手写一个简单的web服务器,应该是可行的,虽然自己写的肯定不会太好,但如果写一遍,那么对与web服务器的运行机制与底层原理会更加的清晰,那么开始写一个简单的web服务器吧。   首先需要分析下http协议,可以在百度百

RealPresence and Media Collaboration 专栏 496

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

python实现并发的方式_python实现并发服务器的几种方式

3.使用多进程和多线程的方式实现并发服务器import socketfrom multiprocessing import Processfrom threading import Threaddef task(sock):while True:try:recv_data = sock.recv(1024)if recv_data:print('accept data:', recv_data.d...

weixin_36474795的博客 700

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Linux服务器1 ---(常用的套接字API函数的二次包裹,简单的单进程模型,简单的多进程/多线程模型支持并发)

一、常用的套接字API函数的二次包裹 对套接字api函数进行包裹,内部加入错误处理,功能与系统的api函数完全相同 ,为了我们容易寻找错误且使用方便。 1、socket套接字函数包裹定义 #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #inclu

scarificed的博客 626

多进程多线程并发服务器代码

多进程多线程并发服务器代码。

Dongjl02的博客 145

python模拟多线程http请求_用python实现自己的http服务器——多进程、多线程、协程、单进程非堵塞版、epoll版...

了解http协议http请求头GET / HTTP/1.1Host: www.baidu.comConnection: keep-alivePragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebK...

weixin_39908588的博客 416

c++网络编程并发处理

client.cpp #include<bits/stdc++.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #define SZ 10 usin...

污miao汪的博客 745

python websocket异步高并发,Python上的多线程Websocket服务器

Please help me to improve this code:import base64import hashlibimport threadingimport socketclass WebSocketServer:def __init__(self, host, port, limit, **kwargs):"""Initialize websocket server.:param ...

weixin_35648005的博客 1906

python实现一个简单的http服务器

用python实现一个简单的http服务器,用户通过浏览器请求任意路径,返回一个固定的页面 # -*- coding: utf-8 -*- import socket def service_client(new_socket): # 为这个客户端返回数据 # 1.接收浏览器发过来的请求,即http请求 # GET / HTTP/1.1 recv_data = new_socket.recv(1024).decode('utf-8') request_header

Jepson的博客 7429

9.3tcp多进程并发模板和多线程并发模板

多进程并发模板#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <signal.h> #include <sys/wait.h> #in

a312024054的专栏 575

多线程并发socket服务示例代码

thread,process,socket

lepton126的专栏 475

【网络编程】Day4 TCP并发服务器

3. 多线程代码写一遍,能否将newfd定义成全局(不行,找原因)发送方:memberSend.c。发送方:boardSend.c。接收方:boardrRcv.c。接收方:memberRcv.c。1. 广播,组播代码重新写一遍。2. 多进程通过模型自己写一遍。4. 上传下载写完。

wangxiasun的博客 328
上一篇: mediasoup部署问题
下一篇: 线程同步
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值