2024-03-19 作业

作业要求:

1> 将白天课堂代码重新实现一遍:

select实现的TCP并发服务器

poll实现的TCP客户端

2> 君子作业

select实现的TCP客户端

poll实现的TCP并发服务器

作业1:

运行代码:
select实现的TCP并发服务器
#include<myhead.h>
#define SER_IP "192.168.117.111"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
	//1.创建套接字sfd
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1==sfd){
		perror("socket error");
		return -1;
	}
	printf("socket success:sfd = %d\n",sfd);
	//端口快速重用
	int reuse = 1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){
		perror("reuse error");
		return -1;
	}
	printf("reuse success\n");
	//2.绑定bind
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
		perror("bind error");
		return -1;
	}
	printf("bind success \n");
	//3.开启监听
	if(listen(sfd,128)==-1){
		perror("listen error");
		return -1;
	}
	printf("listen success\n");
	//4
	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);
	//堵塞文件设置select
	fd_set readfd,tempfd;
	FD_ZERO(&readfd);
	FD_SET(0,&readfd);//放入输入文件
	FD_SET(sfd,&readfd);//放入sfd
	int maxfd=sfd;
	int newfd;
	struct sockaddr_in cin_arr[1024];//存放客户端信息
	char sbuf[128]="";
	while(1){
		tempfd = readfd;
		int res = select(maxfd+1,&tempfd,NULL,NULL,NULL);//筛选tempfd
		if(res==0){
			continue;
		}else if(res = 0){
			perror("select error");
			return -1;
		}

	/********************************/	
		for(int i = 0;i<=maxfd;i++){
			//接受连接请求
			if(!(FD_ISSET(i,&tempfd))){
				continue;
			}	
			if(i==sfd){
				if(FD_ISSET(sfd,&tempfd)){
					if((newfd = accept(sfd,(struct sockaddr *)&cin,&socklen))==-1){
						perror("accept error");
						return -1;
					}
					printf("[%s %d]发来请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
					FD_SET(newfd,&readfd);//将newfd加入检测数组
					if(newfd>maxfd){
						maxfd = newfd;
					}
					cin_arr[newfd]=cin;//cin放入数组
				}
	/**********************************/
			}else if(i==0){
				//输入设置
				if(FD_ISSET(0,&tempfd)){
					bzero(sbuf,sizeof(sbuf));
					fgets(sbuf,sizeof(sbuf)-1,stdin);
					sbuf[strlen(sbuf)-1]=0;
					for(int j=4;j<=maxfd;j++){
						if(FD_ISSET(j,&readfd)){
							send(j,sbuf,strlen(sbuf),0);
							printf("发送成功\n");
						}
					}
				}
	/***********************************/
			}else if(i>3){
				//接受客户端信息
				if(FD_ISSET(i,&tempfd)){
					bzero(sbuf,sizeof(sbuf));
					int ret = recv(i,sbuf,sizeof(sbuf)-1,0);
					if(ret <=0){
						printf("对方已下线\n");
						//除去客户端的文件描述符
						FD_CLR(i,&readfd);
						close(i);
						if(i==maxfd){
							for(int j=maxfd-1;j>=3;j--){
								if(FD_ISSET(j,&readfd)){
									maxfd = j;
									break;
								}
							}//for
						}//if
						continue;
					}//if
					printf("[%s %d]>>>%s\n",inet_ntoa(cin_arr[i].sin_addr),htons(cin_arr[i].sin_port),sbuf);
					strcat(sbuf,"*<*");
					send(i,sbuf,strlen(sbuf),0);
				}//if
			}//i>3
	/************************************/
		}//for

}
	//关闭文件
	close(sfd);
	return 0;
}
 poll实现的TCP客户端
#include<myhead.h>
#define SER_IP "192.168.1.101"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
	//1.创建套接字cfd
	int cfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1==cfd){
		perror("socket error");
		return -1;
	}
	printf("socket success:cfd = %d\n",cfd);
	//连接
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	
	//堵塞文件设置pfd
	struct pollfd pfd[2];
	 pfd[0].fd=0;
	 pfd[0].events=POLLIN;
	 pfd[1].fd=cfd;
	 pfd[1].events=POLLIN;
	char cbuf[128]="";
	//连接
	if(connect(cfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
		perror("connect error");
		return -1;
	}
	printf("connect success\n");
	while(1){
		int res = poll(pfd,2,-1);

		if(res==0){
			continue;
		}else if(res = 0){
			perror("select error");
			return -1;
		}

		//输入设置
		if(pfd[0].revents==POLLIN){
			bzero(cbuf,sizeof(cbuf));
			fgets(cbuf,sizeof(cbuf)-1,stdin);
			cbuf[strlen(cbuf)-1]=0;
			send(cfd,cbuf,strlen(cbuf),0);
		}
		/***********************************/
		//接受客户端信息
		if(pfd[1].revents==POLLIN){
			bzero(cbuf,sizeof(cbuf));
			int ret = recv(cfd,cbuf,sizeof(cbuf),0);
			if(ret <= 0){
				printf("服务器已下线\n");
				return 0;
			}
			printf("服务器发来>>>%s\n",cbuf);
		}
	}
		//关闭文件
		close(cfd);
		return 0;
}
运行截图: 

作业2:

运行代码:
#include<myhead.h>
#define SER_IP "192.168.1.101"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
	//1.创建套接字cfd
	int cfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1==cfd){
		perror("socket error");
		return -1;
	}
	printf("socket success:cfd = %d\n",cfd);
	//连接
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	
	//堵塞文件设置select
	fd_set readfd,tempfd;
	FD_ZERO(&readfd);
	FD_SET(0,&readfd);//放入输入文件
	FD_SET(cfd,&readfd);//放入cfd
	char cbuf[128]="";
	//连接
	if(connect(cfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
		perror("connect error");
		return -1;
	}
	printf("connect success\n");
	while(1){
		tempfd = readfd;
		int res = select(cfd+1,&tempfd,NULL,NULL,NULL);//筛选tempfd
		if(res==0){
			continue;
		}else if(res = 0){
			perror("select error");
			return -1;
		}

		//输入设置
		if(FD_ISSET(0,&tempfd)){
			bzero(cbuf,sizeof(cbuf));
			fgets(cbuf,sizeof(cbuf)-1,stdin);
			cbuf[strlen(cbuf)-1]=0;
			send(cfd,cbuf,strlen(cbuf),0);
		}
		/***********************************/
		//接受客户端信息
		if(FD_ISSET(cfd,&tempfd)){
			bzero(cbuf,sizeof(cbuf));
			recv(cfd,cbuf,sizeof(cbuf),0);
			printf("服务器发来>>>%s\n",cbuf);
		}
	}
		//关闭文件
		close(cfd);
		return 0;
}
poll实现的TCP并发服务器 
#include<myhead.h>
#define SER_IP "192.168.1.101"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
	//1.创建套接字sfd
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1==sfd){
		perror("socket error");
		return -1;
	}
	printf("socket success:sfd = %d\n",sfd);
	//端口快速重用
	int reuse = 1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){
		perror("reuse error");
		return -1;
	}
	printf("reuse success\n");
	//2.绑定bind
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
		perror("bind error");
		return -1;
	}
	printf("bind success \n");
	//3.开启监听
	if(listen(sfd,128)==-1){
		perror("listen error");
		return -1;
	}
	printf("listen success\n");
	//4
	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);
	//堵塞文件设置poll
	struct pollfd pfd[1024];
	pfd[0].fd = 0;
	pfd[0].events=POLLIN;
	pfd[1].fd = sfd;
	pfd[1].events=POLLIN;
	int newfd;
	int num=2;
	struct sockaddr_in cin_arr[1024];//存放客户端信息
	char sbuf[128]="";
	while(1){
		//设置堵塞
		int res = poll(pfd,num,-1);
		if(res==0){
			continue;
		}else if(res == 0){
			perror("select error");
			return -1;
		}

		/********************************/	
		for(int i = 0;i<num;i++){
			//接受连接请求
			if(!(pfd[i].revents==POLLIN)){
				continue;
			}	
			if(i==1){
				if(pfd[i].revents==POLLIN){
					if((newfd = accept(sfd,(struct sockaddr *)&cin,&socklen))==-1){
						perror("accept error");
						return -1;
					}
					printf("[%s %d]发来请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
					pfd[num].fd=newfd;//将newfd加入检测数组
					pfd[num].events=POLLIN;

					cin_arr[newfd]=cin;//cin放入数组
					num++;
				}
				/**********************************/
			}else if(i==0){
				//输入设置
				if(pfd[0].revents==POLLIN){
					bzero(sbuf,sizeof(sbuf));
					fgets(sbuf,sizeof(sbuf)-1,stdin);
					sbuf[strlen(sbuf)-1]=0;
					for(int j=2;j<=num;j++){
						if(pfd[j].events==POLLIN){
							send(pfd[j].fd,sbuf,strlen(sbuf),0);
						}
					}
					printf("发送成功\n");
				}
				/***********************************/
			}else if(i>=2){
				//接受客户端信息
				if(pfd[i].revents==POLLIN){
					bzero(sbuf,sizeof(sbuf));
					int ret = recv(pfd[i].fd,sbuf,sizeof(sbuf)-1,0);
					if(ret <=0){
						printf("对方已下线\n");
						//除去客户端的文件描述符
						close(pfd[i].fd);
						if(i==num-1){
							num--;
						}else{
							pfd[i]=pfd[num-1];
							num--;
						}
						
						continue;
					}//if
					printf("[%s %d]>>>%s\n",inet_ntoa(cin_arr[pfd[i].fd].sin_addr),htons(cin_arr[pfd[i].fd].sin_port),sbuf);
					strcat(sbuf,"*<*");
					send(pfd[i].fd,sbuf,strlen(sbuf),0);
				}//if
			}//i>3
			/************************************/
		}//for

	}
	//关闭文件
	close(sfd);
	return 0;
}
运行截图: 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[项目设计]基于websocket实现网络对战五子棋

项目介绍 该项目旨在实现一个网页端的在线五子棋&#xff0c;将实现登陆、好友、房间、对战、观战、聊天等功能 完成该项目需要了解C、数据库MySQL、基础前端HTML/CSS/JS/Ajax、网络协议WebSocket 项目源码&#xff1a;azhe1/online_gobang - 码云 - 开源中国 (gitee.com) …

国产-高精度、可编程数字温度传感芯片-MY18E20

由工采代理的MY18E20是一款国产高精度可编程的数字模拟混合信号温度传感芯片&#xff1b;感温原理基于CMOS半导体PN节温度与带隙电压的特性关系&#xff0c;经过小信号放大、模数转换、数字校准补偿后&#xff0c;数字总线输出&#xff0c;具有精度高、一致性好、测温快、功耗低…

vue前端解析jwt

vue前端解析jwt 我们可以用在线解析看解析的结果&#xff1a;https://www.lddgo.net/encrypt/jwt-decrypt 但是如果在前端需要解析token&#xff0c;拿到其中的权限信息&#xff0c;可以这样解决。 在线的&#xff1a; 完美解决&#xff1a; 代码&#xff1a; function par…

MySQL下载和安装部署

4.1 简介 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公 司开发&#xff0c;现在已经属于 Oracle 旗下产品。MySQL 是最流行的关系型数据 库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS(Relational Database Management System&…

AI系统性学习—LangChain入门

文章目录 1、LangChain入门1.1 简介1.2 架构1.3 核心概念1.2 快速入门1.3 安装 2、LangChain Prompt Template2.1 什么是提示词模版2.1 创建一个提示词模版2.2 聊天消息提示词模版2.3 模版追加示例 3、语言模型3.1 LLM基础模型3.2 LangChain聊天模型3.3 自定义模型3.4 输出解析…

linux网络服务学习(2):vsftp

1.什么是vsftp vsftp是linux服务器上的一款使用ftp协议的软件&#xff0c;是linux上使用最广泛的ftp服务端软件 ftp协议是使用明文传输的&#xff0c;很不安全&#xff0c;一般用于局域网内的文件上传、下载 2.vsftp连接类型 ftp连接要用到2个端口&#xff1a;21、20端口。…

高效备考2024年AMC10:吃透2000-2023年1250道真题(限时免费送)

我们今天继续来随机看5道AMC10真题&#xff0c;以及详细解析&#xff0c;这些题目来自1250道完整的官方历年AMC10真题库。通过系统研究和吃透AMC10的历年真题&#xff0c;参加AMC10的竞赛就能拿到好名次。即使不参加AMC10竞赛&#xff0c;掌握了这些知识和解题思路后初中和高中…

阿里巴巴求职者必看:@SpringMVC?面试准备全攻略!

如有疑问或者更多的技术分享,欢迎关注我的微信公众号“知其然亦知其所以然”! 大家好,我是小米!今天我们来聊聊阿里巴巴面试中常见的一个热门话题:@SpringMVC!如果你对这个话题感兴趣,那就跟着我一起来揭开这个技术的神秘面纱吧! @Controller 在SpringMVC中,我们经…

Java-seata 头参数透传问题步骤详解-arthas

seata分布式事物下游不能回滚的问题; 初步分析headers中TX_XID 没有传给下游系统 通过拦截器打印上游服务日志和下游服务日志打印&#xff0c;影响上游服务不能传header 中自定意义参数的地方是启用线程的熔断策略。 feign:hystrix:enabled: false #不启用client: config:def…

C数据类型(C语言)---变量的类型决定了什么?

目录 数据类型&#xff08;Data Type&#xff09; 变量的类型决定了什么&#xff1f; &#xff08;1&#xff09;不同类型数据占用的内存大小不同 如何计算变量或类型占内存的大小 &#xff08;2&#xff09;不同数据类型的表数范围不同 &#xff08;3&#xff09;不同类型…

Jmeter-基础元件使用(二)

一、Jmeter属性 当我们想要在不同线程组中使用某变量&#xff0c;就需要使用属&#xff0c;此时Jmeter属性的设置需要函数来进行set和get操作 1.创建set函数 2.然后采用Beanshell取样器进行函数执行 3.调用全局变量pro_id 4.将上面生成的函数字符串粘贴到另一个线程组即可…

QB PHP 多语言配置

1&#xff1a; 下载QBfast .exe 的文件 2&#xff1a; 安装的时候 &#xff0c;一定点击 仅为我 安装 而不是 所有人 3&#xff1a; 如果提示 更新就 更新 &#xff0c; 安装如2 4&#xff1a; 如果遇到 新增 或者编辑已经 配置的项目时 不起作用 &#xff1a; 右…

onnx 推理报错 Process finished with exit code 139

onnxruntime可以导出模型&#xff0c;但使用onnx推理时程序异常退出如下&#xff1a; Process finished with exit code 139 推理时使用了以下模板&#xff0c;执行到ort_session.run后就会异常错误码退出。 import onnxruntime onnx_file_name "xxxxxx.onnx" ort_…

登高望远 儒风泰山 | 泰山酒业儒风泰山高端系列新品亮相云端

“尊敬的各位旅客大家上午好&#xff0c;很高兴与您相聚在万米云端&#xff0c;本次航班由泉城济南飞往天府之国成都......”&#xff13;月&#xff11;&#xff16;日&#xff0c;伴随着乘务长优美的声音&#xff0c;山东航空携手泰山酒业打造的“登高望远 儒风泰山”儒风泰…

Redis设计原理简介

键值存储模型&#xff1a; Redis是一个基于内存的键值对存储系统&#xff0c;它支持五种基本数据结构&#xff08;字符串String、哈希Hash、列表List、集合Set、有序集合Sorted Set&#xff09;以及几种高级数据结构如Bitmaps、HyperLogLogs等。 单线程架构&#xff1a; Redis采…

【刷题】滑动窗口入门

送给大家一句话&#xff1a; 那脑袋里的智慧&#xff0c;就像打火石里的火花一样&#xff0c;不去打它是不肯出来的。——莎士比亚 滑动窗口入门 认识滑动窗口Leetcode 209. 长度最小的子数组题目描述算法思路 Leetcode 3. 无重复字符的最长子串题目描述算法思路 Leetcode 1004…

Python数据结构实验 顺序表的实现

一、实验目的 1&#xff0e;掌握用Python定义线性表的顺序存储类型&#xff1b; 2&#xff0e;掌握用Python调试顺序表的基本方法&#xff1b; 3&#xff0e;掌握顺序表的基本操作&#xff0c;插入、删除、查找、以及有序顺序表的合并等算法的实现&#xff1b; 二、实验环境…

首页效果炫酷的wordpress免费主题模板

视频背景免费WP主题 简洁大气的视频背景wordpress主题&#xff0c;找大视频背景的主题可以看看这个。 https://www.wpniu.com/themes/193.html 红色全屏大图WP主题 非常经典的一款免费wordpress主题&#xff0c;红色全屏大图满足多行业使用。 https://www.wpniu.com/themes…

sqli-labs训练平台靶场详解!!!!

sqli-labs 是一个专业的 SQL 注入练习平台,该平台包含常见的注入类型,环境共有65个 SOL 注入漏洞&#xff0c;旨在帮助Web安全学习者对SQL注入漏洞有一个全面的了解。 项目地址为:GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based…

JAVA多线程之同步

文章目录 1. wait/notify1.1 基本使用1.2 优化使用 2. Park & Unpark2.1 基本使用2.2 基本原理 3. 线程状态4. 活跃性4.1 死锁4.1.1 死锁介绍4.2.2 死锁定位 4.3 活锁4.4 饥饿 锁的使用&#xff0c;其实就是为了使用临界资源的时候来进行同步&#xff0c;即一个线程用完一个…