2.7作业

分别通过select、多进程、多线程实现一个并发服务器

select

#include <myhead.h>
#define PORT 8888             
#define IP "192.168.250.100"
int main(int argc, const char *argv[])
{//1、创建用于接受连接的套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd == -1){perror("socket error");return -1;}//设置端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){perror("setsockopt error");return -1;}//2、绑定IP地址和端口号struct sockaddr_in sin;sin.sin_family     = AF_INET;       sin.sin_port     = htons(PORT);       sin.sin_addr.s_addr = inet_addr(IP);  if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))==-1){perror("bind error");return -1;}//3、将套接字设置成被动监听状态if(listen(sfd, 128) == -1){perror("listen error");return -1;}//4、阻塞等待客户端连接请求,如果有新的客户端连接,则创建一个新的用于通信的套接字struct sockaddr_in cin;            cin.sin_family     = AF_INET;socklen_t socklen = sizeof(cin);          定义一个用于检测文件描述符的集合fd_set readfds, tempfds;                       FD_ZERO(&readfds);FD_SET(sfd, &readfds);          FD_SET(0, &readfds);            //定义一个容器char buf[128] = "";int res = 0;             int newfd = -1;          int maxfd = sfd;          //用于存放客户端地址信息结构体struct sockaddr_in saveCin[1024];       while(1){tempfds = readfds;//使用select阻塞等待集合中的文件描述符有事件产生res = select(maxfd+1, &tempfds, NULL, NULL, NULL);if(res == -1){perror("select error");return -1;}else if(res == 0){printf("time out\n");return -1;}//遍历所有集合中文件描述符for(int i=0; i<=maxfd; i++){//判断当前i是否在集合中,如果不在,直接判断下一个if(!FD_ISSET(i, &tempfds)){continue;}//判断sfd是否还在集合中if( i == sfd){//4.2、阻塞接收客户端的链接请求,并且获取客户端的地址信息newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);if(newfd == -1){perror("accept error");return -1;}将newfd放入readfds中FD_SET(newfd , &readfds);//更新maxfdif(newfd > maxfd){maxfd = newfd;}//将最新的客户端套接字放入数组的下标为new的位置saveCin[newfd] = cin;}else if(i == 0 )    //判断是否是终端输入{char buf1[128] = "";bzero(buf, sizeof(buf));//从终端获取数据fgets(buf, sizeof(buf), stdin);       buf[strlen(buf)-1]='\0';printf("终端输入:%s\n", buf);sprintf(buf1, "%s%s", "System:", buf);//将数据发送给所有客户端for(int j=4; j<=maxfd; j++){send(j, buf1,sizeof(buf1), 0);}}else{//5、收发数据使用newfd完成通信char buf[128] = "";//清空字符串bzero(buf, sizeof(buf));int ret = recv(i, buf, sizeof(buf), 0);        //从套接字中读取客户端发来的消息//判断收到的结果if(ret == 0){printf("客户端已经下线\n");    close(i);            //将当前的文件描述符从集合中删除FD_CLR(i, &readfds);//更新maxfdfor(int j=maxfd; j>=0; j--){//判断当前的j是否在集合中if(FD_ISSET(j, &readfds)){maxfd = j;break;}}continue;    }else if(ret < 0){perror("recv error");return -1;}printf("[%s:%d]:%s\n", inet_ntoa(saveCin[i].sin_addr), ntohs(saveCin[i].sin_port), buf);//将读取的信息,加上一些字符发送回去strcat(buf, "*_*");send(i, buf, sizeof(buf), 0); }}}//6、关闭所有套接字close(sfd);       return 0;
}

现象

2.多进程

#include <myhead.h>
#define PORT 8888             
#define IP "192.168.250.100"
//定义函数处理客户端信息
int deal_cli_msg(int newfd, struct sockaddr_in cin)
{//收发数据使用newfd完成通信char buf[128] = "";while(1){//清空字符串bzero(buf, sizeof(buf));int res = recv(newfd, buf, sizeof(buf), 0);      //判断收到的结果if(res == 0){printf("客户端已经下线\n");break;}else if(res < 0){perror("recv error");return -1;}printf("[%s:%d]:%s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);//将读取的信息,加上一些字符发送回去strcat(buf, "*_*");send(newfd, buf, sizeof(buf), 0); }close(newfd);       return 0;
}
//定义信号处理函数
void handler(int signo)
{if(signo == SIGCHLD){while(waitpid(-1, NULL, WNOHANG) > 0);  }
}
int main(int argc, const char *argv[])
{//1、创建用于接受连接的套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd == -1){perror("socket error");return -1;}//设置端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){perror("setsockopt error");return -1;}//2、绑定IP地址和端口号struct sockaddr_in sin;sin.sin_family     = AF_INET;       sin.sin_port     = htons(PORT);       sin.sin_addr.s_addr = inet_addr(IP);  if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))==-1){perror("bind error");return -1;}//3、将套接字设置成被动监听状态if(listen(sfd, 128) == -1){perror("listen error");return -1;}//4、阻塞等待客户端连接请求,如果有新的客户端连接,则创建一个新的用于通信的套接字struct sockaddr_in cin;            cin.sin_family     = AF_INET;socklen_t socklen = sizeof(cin); //定义子进程变量pid_t pid;//将SIGCHLD信号绑定到自定义信号处理函数中if(signal(SIGCHLD, handler) == SIG_ERR){perror("signal error");return -1;}while(1){    //4.2、阻塞接收客户端的链接请求,并且获取客户端的地址信息int newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);if(newfd == -1){perror("accept error");return -1;}//创建子进程,让子进程完成通信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;}}//6、关闭所有套接字close(sfd); return 0;
}

现象

多线程

#include <myhead.h>
#define PORT 8888             
#define IP "192.168.250.100"
//定义用于向线程体传参的结构体类型
struct msg_info
{int newfd;struct sockaddr_in cin;
};
//定义线程体函数
void *deal_cli_msg(void *arg)
{//获取主线程传递的信息int newfd = ((struct msg_info*)arg) -> newfd;struct sockaddr_in cin = ((struct msg_info*)arg) -> cin;//收发数据使用newfd完成通信char buf[128] = "";while(1){//清空字符串bzero(buf, sizeof(buf));//从套接字中读取客户端发来的消息int res = recv(newfd, buf, sizeof(buf), 0);        //判断收到的结果if(res == 0){printf("客户端已经下线\n");break;}else if(res < 0){perror("recv error");return NULL;}printf("[%s:%d]:%s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);//将读取的信息,加上一些字符发送回去strcat(buf, "*_*");send(newfd, buf, sizeof(buf), 0); }close(newfd);    pthread_exit(NULL);   
}
int main(int argc, const char *argv[])
{//1、创建用于接受连接的套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd == -1){perror("socket error");return -1;}//设置端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){perror("setsockopt error");return -1;}//2、绑定IP地址和端口号struct sockaddr_in sin;sin.sin_family     = AF_INET;       sin.sin_port     = htons(PORT);       sin.sin_addr.s_addr = inet_addr(IP);  if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))==-1){perror("bind error");return -1;}//3、将套接字设置成被动监听状态if(listen(sfd, 128) == -1){perror("listen error");return -1;}//4、阻塞等待客户端连接请求,如果有新的客户端连接,则创建一个新的用于通信的套接字struct sockaddr_in cin;            cin.sin_family     = AF_INET;socklen_t socklen = sizeof(cin); while(1){//阻塞接收客户端的链接请求,并且获取客户端的地址信息int newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);if(newfd == -1){perror("accept error");return -1;}//定义用于向线程体传参的结构体变量struct msg_info info = {newfd, cin};//创建分支线程用于通信pthread_t tid;if(pthread_create(&tid, NULL, deal_cli_msg, &info) != 0){printf("分支线程创建失败\n");return -1;}//将该线程分离if(pthread_detach(tid) != 0){printf("分离失败\n");return -1;}}//6、关闭所有套接字close(sfd); return 0;
}

现象

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

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

相关文章

C++ || 模板初阶 | 函数模板 | 类模板

泛型编程 泛型编程&#xff0c;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段。模板是泛型编程的基础。 可以理解为活字印刷术类似的方式。 函数模板 函数模板概念 函数模板&#xff0c;代表一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用…

Centos7.9安装SQLserver2017数据库

Centos7.9安装SQLserver2017数据库 一、安装前准备 挂载系统盘 安装依赖 yum install libatomic* -y 二、yum方式安装 # 配置 yum 源 wget -O /etc/yum.repos.d/mssql-server.repo https://packages.microsoft.com/config/rhel/7/mssql-server-2017.repoyum clean all yum…

洛谷:P1219 [USACO1.5] 八皇后 Checker Challenge(dfs深度优先遍历求解)

题目描述 一个如下的 6666 的跳棋棋盘&#xff0c;有六个棋子被放置在棋盘上&#xff0c;使得每行、每列有且只有一个&#xff0c;每条对角线&#xff08;包括两条主对角线的所有平行线&#xff09;上至多有一个棋子。 上面的布局可以用序列 2 4 6 1 3 52 4 6 1 3 5 来描述&am…

Bagging的随机森林;Boosting的AdaBoost和GBDT

集成学习应用实践 import numpy as np import os %matplotlib inline import matplotlib import matplotlib.pyplot as plt plt.rcParams[axes.labelsize] 14 plt.rcParams[xtick.labelsize] 12 plt.rcParams[ytick.labelsize] 12 import warnings warnings.filterwarnin…

【保姆级教程|YOLOv8改进】【7】多尺度空洞注意力(MSDA),DilateFormer实现暴力涨点

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

websocket具体实践

websocket具体实践 参考&#xff1a; 如何使用websocket WebSocket客户端连接不上和掉线的问题以及解决方案 继6月份对websocket一顿了解之后&#xff0c;我们的项目也要上websocket了&#xff0c;虽然这部分不是我做&#xff0c;但是借此机会&#xff0c;我也想要尝试一下&am…

VS无法使用万能头文件#include <bits/stdc++.h> 的解决办法

第一步在vs中打出可以使用的头文件 如#include<cmath> 点击F12转到文档 上面窗口右键找到打开所在文件夹 创建一个名字为bits的文件夹 里面创建一个text文件 // C includes used for precompiling -*- C -*-// Copyright (C) 2003-2015 Free Software Foundation, In…

【开源】JAVA+Vue.js实现开放实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…

TryHackMe-Vulnerability Capstone练习

本文相关的TryHackMe实验房间链接&#xff1a;TryHackMe | Vulnerability Capstone 先nmap扫一下 接下来我们访问一下 接下来我们searchsploit找一下漏洞 searchsploit Fuel CMS 执行漏洞exp&#xff08;此处使用TryHackMe中的box&#xff09; 如果使用本地机需要下载exp&am…

孙思邈中文医疗大模型

孙思邈, 唐代医药学家、道士, 被后人尊称为"药王". 其十分重视民间的医疗经验, 不断积累走访, 及时记录下来, 写下著作《千金要方》. 唐朝建立后, 孙思邈接受朝廷的邀请, 与政府合作开展医学活动, 完成了世界上第一部国家药典《唐新本草》. 孙思邈中医药大模型(简称:…

手把手教你激活FL Studio 21.2.2.3914中文破解版2024年图文激活教程以及如何设置中文language

FL Studio 21.2.2.3914软件简介 fl studio 21.2.2.3914中文破解版作为一款极具创意性的音乐软件工作站软件&#xff0c;FL Studio已经成为了许多音乐制作人和音乐爱好者的首选。最新的FL Studio 21.2.2.3914中文破解版的发布&#xff0c;无疑将会引起更多人的关注。 ​ FL St…

力扣热门100题 - 4.寻找两个正序数组的中位数

力扣热门100题 - 4.寻找两个正序数组的中位数 题目描述&#xff1a;示例&#xff1a;提示&#xff1a;解题思路&#xff1a;代码&#xff1a; 题目链接&#xff1a;4.寻找两个正序数组的中位数 题目描述&#xff1a; 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&a…

微软Windows生态是怎么打造成功的?

&#xff08;1&#xff09;2015年Windows10&#xff1a;兼容性 我不得不再次佩服一下微软&#xff0c;Windows10是2015年出品的&#xff0c;但是仍然能正常运行绝大多数的Windows95软件&#xff0c;不用做任何的适配修改&#xff0c;连重新编译都不用&#xff0c;运行照样正常。…

Python调用matlab程序

matlab官网&#xff1a;https://ww2.mathworks.cn/?s_tidgn_logo matlab外部语言和库接口&#xff0c;包括 Python、Java、C、C、.NET 和 Web 服务。 matlab和python的版本 安装依赖配置 安装matlab的engine 找到matlab的安装目录&#xff1a;“xxx\ extern\engines\python…

华为WLAN无线配置实验

上面大概讲了配置的思路与原理&#xff0c;这里开始实际配置下。 一般建议采用旁挂AC&#xff0c;然后划分独立的设备管理网段&#xff0c;通过DHCP进行获取地址&#xff0c;其它的地址、接口、路由正常配置即可。 一、基本配置 拓扑图 AR1: # 配置接口地址和路由 interface Gi…

ElasticSearch-ElasticSearch实战-仿京东商城搜索(高亮)

注&#xff1a;此为笔者学习狂神说ElasticSearch的实战笔记&#xff0c;其中包含个人的笔记和理解&#xff0c;仅做学习笔记之用&#xff0c;更多详细资讯请出门左拐B站&#xff1a;狂神说!!! 七、ElasticSearch实战 仿京东商城搜索&#xff08;高亮&#xff09; 1、工程创建…

电脑插上u盘后看不到u盘?3个解决方法

随着U盘在我们日常生活和工作中的广泛应用&#xff0c;有时候插入U盘后却发现电脑无法正确识别&#xff0c;这对用户的数据传输和文件管理带来了困扰。本文将介绍电脑插上u盘后看不到u盘的常见原因&#xff0c;并提供三种有效的解决方法&#xff0c;以帮助用户迅速解决这一问题…

如何解锁屏幕破损的 iPhone

iPhone 15 是 Apple 最新、最出色的智能手机。它拥有时尚的设计、尖端的技术和众多功能&#xff0c;使其成为市场上最令人垂涎​​的设备之一。不幸的是&#xff0c;与所有智能手机一样&#xff0c;iPhone 14 容易发生可能导致屏幕破裂的事故和事故。破损的屏幕可能是毁灭性的&…

第二讲:数据结构 AcWing 826. 单链表

目录 数组模拟链表数组模拟单链表 单链表思路 && 代码 看图更好理解推荐一下y总的刷题网站 数组模拟链表 笔试的题目大部分 大部分涉及到链表都是十万级别的 用数组的方式创建链表速度很快&#xff0c;不会超时&#xff0c;而如果用new 一个结构体的话 大部分就是比较…

《Git 简易速速上手小册》第9章:Git 工作流程定制(2024 最新版)

文章目录 9.1 选择合适的工作流9.1.1 基础知识讲解9.1.2 重点案例&#xff1a;为中等规模的 Python 项目选择 Feature Branch 工作流9.1.3 拓展案例 1&#xff1a;适应 Gitflow 工作流的大型项目9.1.4 拓展案例 2&#xff1a;使用 Forking 工作流的开源 Python 项目 9.2 定制化…