Linux 基本语句_15_Tcp并发服务器

news2024/11/24 17:55:48

原理:

利用父子进程。父进程接收客户端的连接请求,子进程处理客户端的数据处理操作,两者各施其职。最终实现能够多个客户端连接一个服务端的操作。

代码:

服务端代码:

#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

#define N 128

void handler(int sig){
	wait(NULL); // 不关心子进程状态,等待子进程终止,回收其资源 
}

int main(int argc, const char *argv[]){
	
	int sockfd, acceptfd;
	
	struct sockaddr_in severaddr, clientaddr; // 存储客户端和服务器的地址信息 
	socklen_t addrlen = sizeof(severaddr);
	char buf[N] = "";
	pid_t pid;
	
	bzero(&severaddr, addrlen);  
	bzero(&clientaddr, addrlen); // 清除特定长度的区域 
	
	if(argc < 3){
		printf("argc number error\n");
		return -1;
	}
	
	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ // IPv4协议、流式套接字 (创建套接字) 
		printf("socket create error\n");
		return -1;
	}
	
	/* 填充信息 */
	
	severaddr.sin_family = AF_INET;
	severaddr.sin_addr.s_addr = inet_addr(argv[1]);
	severaddr.sin_port = htons(atoi(argv[2]));
	
	/* 将套接字与服务器网络信息结构体绑定 */
	
	if(bind(sockfd, (struct sockaddr *) &severaddr, addrlen) < 0){
		printf("bind error\n");
		return -1;
	}
	
	if(listen(sockfd, 5) < 0){ // 设置被动监听模式 
		printf("listen error\n");
		return -1; 
	}
	
	signal(SIGUSR1, handler); // 注册一个信号 
	
	while(1){ // 等待客户端连接请求 
		if((acceptfd = accept(sockfd, (struct sockaddr *) &clientaddr, &addrlen)) < 0){ // 阻塞等待 
			printf("accept error\n");
		}
		
		printf("ip : %s, port : %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
		
		pid = fork(); // 创建子进程 
		
		if(pid < 0){
			printf("fork error\n");
			return -1;
		}
		else if(pid == 0){ // 子进程 
			close(sockfd); // 只需要处理信息,不负责客户端连接
			
			while(1){
				ssize_t bytes;
				if((bytes = recv(acceptfd, buf, N, 0)) < 0){
					printf("recv error\n");
					return -1;
				}
				else if(bytes == 0){
					printf("no data\n");
				}
				else{
					if(strncmp(buf, "quit", 4) == 0){
						printf("client quit\n");
						sleep(1);
						break;
					}
					else{
						printf("client: %s\n", buf);
						strcat(buf, "-server");
						
						if(send(acceptfd, buf, N, 0) < 0){
							printf("send error\n");
							return -1;
						}
					}
				}
			}
			kill(getppid(), SIGUSR1);
			exit(0); 
		}
		else{
			close(acceptfd); // 释放资源,关闭与客户端连接 
		} 
	}
	return 0; 
}

客户端代码:

#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

#define N 128

void handler(int sig){
	wait(NULL); // 不关心子进程状态,等待子进程终止,回收其资源 
}

int main(int argc, const char *argv[]){
	
	int sockfd, acceptfd;
	
	struct sockaddr_in serveraddr, clientaddr; // 存储客户端和服务器的地址信息 
	socklen_t addrlen = sizeof(serveraddr);
	char buf[N] = "";
	pid_t pid;
	
	bzero(&serveraddr, addrlen);  
	bzero(&clientaddr, addrlen); // 清除特定长度的区域 
	
	if(argc < 3){
		printf("argc number error\n");
		return -1;
	}
	
	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ // IPv4协议、流式套接字 (创建套接字) 
		printf("socket create error\n");
		return -1;
	}
	
	/* 填充信息 */
	
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
	serveraddr.sin_port = htons(atoi(argv[2]));
	
	/* 将套接字与服务器网络信息结构体绑定 */
	
/*	if(bind(sockfd, (struct sockaddr *) &severaddr, addrlen) < 0){
		printf("bind error\n");
		return -1;
	}
	
	if(listen(sockfd, 5) < 0){ // 设置被动监听模式 
		printf("listen error\n");
		return -1; 
	}

	
	signal(SIGUSR1, handler); // 注册一个信号 
*/
    if(connect(sockfd, (struct sockaddr *) &serveraddr, addrlen) < 0){ // 发送客户端连接请求 
    	printf("connect error\n");
    	return -1;
	}
	
	while(1){ // 等待客户端连接请求 
        fgets(buf, N, stdin);
		buf[strlen(buf) - 1] = '\0';
		
		if(send(sockfd, buf, N, 0) < 0){
			printf("send error\n");
			return -1;
		}
		else{
			if(strncmp(buf, "quit", 4) == 0){
				break;
			}
		}
		if(recv(sockfd, buf, N, 0) < 0){
			printf("recv error\n");
			return -1;
		}
		printf("server: %s\n", buf); 
	}
	return 0; 
}

效果:

在这里插入图片描述

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

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

相关文章

时序预测 | Python实现LSTM-Attention-XGBoost组合模型电力需求预测

时序预测 | Python实现LSTM-Attention-XGBoost组合模型电力需求预测 目录 时序预测 | Python实现LSTM-Attention-XGBoost组合模型电力需求预测预测效果基本描述程序设计参考资料预测效果 基本描述 该数据集因其每小时的用电量数据以及 TSO 对消耗和定价的相应预测而值得注意,从…

Eslint 要被 Oxlint替换了吗

什么是 Oxlint 由于最近的rust在前端领域的崛起,基于rust的前端生态链遭到rust底层重构,最近又爆出OxLint,是一款基于Rust的linter工具。Oxlint在国外前端圈引起热烈讨论,很多大佬给出了高度评价。 事实上,Oxlint 是 Oxc 项目旗下的一款产品,专为 JavaScript 和 TypeSc…

SLAM算法与工程实践——SLAM基本库的安装与使用(5):Ceres优化库

SLAM算法与工程实践系列文章 下面是SLAM算法与工程实践系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 SLAM算法与工程实践系列文章链接 下面是专栏地址&#xff1a; SLAM算法与工程实践系列专栏 文章目录 SLAM算法与工程实践系列文章SLAM算法与工程实践…

【️接口和抽象类的区别,如何选择?】

✅接口和抽象类的区别&#xff0c;如何选择&#xff1f; ✅ 接口和抽象类的区别✅方法定义✅修饰符✅构造器✅继承和实现✅单继承 、 多实现✅职责不同 ✅什么是模板方法模式&#xff0c;有哪些应用呢&#xff1f;✅典型理解✅示例&#x1f4a1;思考 ✅你在工作中是如何使用设计…

Swin-Transformer 在图像识别中的应用

1. 卷积神经网络简单介绍 图像识别任务主要利用神经网络对图像进行特征提取&#xff0c;最后通过全连接层将特征和分类个数进行映射。传统的网络是利用线性网络对图像进行分类&#xff0c;然而图像信息是二维的&#xff0c;一般来说&#xff0c;图像像素点和周围邻域像素点相关…

【MISRA C 2012】Rule 5.4 宏标识符应该是不同的

1. 规则1.1 原文1.2 分类 2. 关键描述3. Example4. 代码实例 1. 规则 1.1 原文 1.2 分类 规则5.4&#xff1a;宏标识符应该是不同的 Required要求类规范。 2. 关键描述 该规则要求&#xff0c;当定义宏时&#xff0c;其名称与: •当前定义的其他宏的名称;和 •参数的名称。…

网线市场现状与发展趋势预测

随着物联网、5G、云计算等技术的迅速发展&#xff0c;全球对于高速、稳定的网络需求急剧增长&#xff0c;这进一步推动了网线市场的发展。各种网络应用场景&#xff0c;从家庭到企业、数据中心到智能城市&#xff0c;都需要大量的高质量网线来支持数据传输和通信需求。本文将对…

windows 10 安装和配置nginx

1 下载nginx 1.1 下载地址&#xff1a;http://nginx.org/en/download.html 1.2 使用解压到安装目录 1.3 更改配置 conf目录下nginx.conf 修改为未被占用的端口&#xff0c;地址改成你的地址 server {listen 9999;server_name localhost;#charset koi8-r;#access_lo…

超文本传送协议HTTP

目录 HTTP简介&#xff1a; URL的格式&#xff1a; HTTP协议的特点&#xff1a; HTTP/1.0协议&#xff1a; HTTP/1.1协议&#xff1a; HTTP/2: HTTP代理服务器&#xff1a; HTTP的报文结构&#xff1a; 请求报文的特点&#xff1a; 响应报文的特点&#xff1a; Cook…

eNSP小实验---(简单混合)

实验目的&#xff1a;实现vlan10 vlan20 172网段用户互访 1.拓扑图 2.配置 PC1 其它同理 SW4 <Huawei> <Huawei>u t m Info: Current terminal monitor is off. <Huawei>sys <Huawei>sys Enter system view, return user view with CtrlZ. [Hua…

idea第一次提交到git(码云)

1.先创建一个仓库 2.将idea和仓库地址绑定 2.将idea和仓库地址绑定

升华 RabbitMQ:解锁一致性哈希交换机的奥秘【RabbitMQ 十】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 升华 RabbitMQ&#xff1a;解锁一致性哈希交换机的奥秘【RabbitMQ 十】 前言第一&#xff1a;该插件需求为什么需要一种更智能的消息路由方式&#xff1f;一致性哈希的基本概念&#xff1a; 第二&…

Vue学习计划-Vue2--VueCLi(七)nextTick、、浏览器本地缓存、脚手架配置代理

1. nextTick 语法&#xff1a; this.$nextTick(回调函数)作用&#xff1a;在下一次DOM更新结束后执行其指定的回调什么时候用&#xff1a; 当改变数据后&#xff0c;要基于更新后的新DOM进行某些操作时&#xff0c;要在nextTick所指定的回调函数中执行 **举个栗子&#xff1a;…

nodejs+vue+微信小程序+python+PHP运动项目推荐系统-计算机毕业设计推荐

运动项目推荐系统的整体架构确定以后&#xff0c;再来看运动项目推荐系统的主要功能模块图。整体的功能模块包括前台和后台&#xff0c;前台只要实现了注册用户功能&#xff0c;主要的页面&#xff0c;包括首页&#xff0c;体育资讯&#xff0c;体育项目&#xff0c;公告信息等…

机器学习 高维数据可视化:t-SNE 降维算法

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

NSSCTF靶场练习[HUBUCTF 2022 新生赛]

[HUBUCTF 2022 新生赛]simple_RE 签到题 一个base64编码&#xff0c;自定义了码表、 [HUBUCTF 2022 新生赛]ezPython py逆向&#xff0c;用在线网站反编译一下 先解一次base64&#xff0c;再解一次base58 接着再把 password转换成 bytes的形式做一次md5加密就好 from Crypto…

基于ASF-YOLO融合空间特征和尺度特征的新型注意力尺度序列融合模型开发构建医学场景下细胞分割检测识别系统,以【BCC、DSB2018数据集为基准】

作者提出了一种新的基于注意尺度序列融合的YOLO框架&#xff08;ASF-YOLO&#xff09;&#xff0c;该框架结合了空间和尺度特征&#xff0c;实现了准确快速的细胞实例分割。基于YOLO分割框架&#xff0c;我们使用尺度序列特征融合&#xff08;SSFF&#xff09;模块来增强网络的…

【Java代码审计】XSS篇

【Java代码审计】XSS篇 1.Java中XSS常见触发位置2.反射型XSS3.存储型XSS4.XSS漏洞修复 1.Java中XSS常见触发位置 XSS漏洞产生后必然会有相关的输入/输出&#xff0c;因此我们只需快速找到这些输入/输出点&#xff0c;即可快速地进行跟踪发现漏洞。输入在Java中通常使用“reque…

基于Java SSM框架实现疫情居家办公OA系统项目【项目源码+论文说明】

基于java的SSM框架实现疫情居家办公OA系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识…

基于循环神经网络长短时记忆(RNN-LSTM)的大豆土壤水分预测模型的建立

Development of a Soil Moisture Prediction Model Based on Recurrent Neural Network Long Short-Term Memory in Soybean Cultivation 1、介绍2、方法2.1 数据获取2.2.用于预测土壤湿度的 LSTM 模型2.3.土壤水分预测的RNN-LSTM模型的建立条件2.4.预测土壤水分的RNN-LSTM模型…