2024.3.5

作业1、使用select实现tcp服务器端,poll实现tcp客户端

服务器端:

#include <myhead.h>
#define SER_IP "192.168.199.131"    //服务端IP
#define SER_PORT 8888               //服务端端口号
 
int main(int argc, const char *argv[])
{
	//1.创建用于连接的套接字
	int sfd=socket(AF_INET,SOCK_STREAM,0);
	if(sfd==-1){
		perror("socket error");
		return -1;
	}
	printf("sfd=%d\n",sfd);
 
	//端口号快速重用
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){
		perror("setsockopt error");
		return -1;
	}
	printf("端口号快速重用成功\n");
 
	//2.绑定端口号和IP
	//填充地址信息结构体
	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)){
		perror("listen error");
		return -1;
	}
	printf("listen sucess\n");
 
	//定义地址信息结构体用于接收客户端信息
	struct sockaddr_in cin;
	socklen_t socklen=sizeof(cin);
 
	char sbuf[128]="";
 
	//创建容器
	fd_set readfds,tempfds;
	//清空容器
	FD_ZERO(&readfds);
	//将文件描述符放入容器
	FD_SET(sfd,&readfds);
	FD_SET(0,&readfds);
 
	int maxfd=sfd;      //记录最大文件描述符
	int newfd=-1;
 
	struct sockaddr_in cin_arr[1024];
 
 
	while(1)
	{
		//将容器复制一份
		tempfds=readfds;
 
		//监测容器中是否有事件发生
		int res=select(maxfd+1,&tempfds,NULL,NULL,NULL);
		if(res==-1){
			perror("select error");
			return -1;
		}else if(res==0){
			printf("timeout\n");
			return -1;
		}
 
		//有事件发生,执行相应任务
		for(int i=0;i<=maxfd;i++)
		{
			//判断当前文件描述符是否在容器中
			if(!FD_ISSET(i,&tempfds)){
 
				continue;
			}
			if(i==sfd)
			{
				//阻塞等待客户端连接
				newfd=accept(i,(struct sockaddr*)&cin,&socklen);
				if(newfd==-1){
					perror("accept error");
					return -1;
				}
				printf("您有新的用户以上线:newfd=%d\n",newfd);
				printf("IP:%s  端口号:%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
 
				//将新的文件描述符放入容器
				FD_SET(newfd,&readfds);
				cin_arr[newfd]=cin;
				//更新maxfd
				if(newfd>maxfd){
					maxfd=newfd;
				}
			}else if(i==0)
			{
 
				//从终端获取数据
				fgets(sbuf,sizeof(sbuf),stdin);
				sbuf[strlen(sbuf)-1]=0;
				printf("键盘输入:%s\n",sbuf);
 
				//给客户端发送数据
				for(int j=4;j<=maxfd;j++)
				{
					send(j,sbuf,strlen(sbuf),0);
				}
			}else
			{
				//进行数据收发
				char rbuf[128]="";
 
				bzero(rbuf,sizeof(rbuf));
 
				//接收数据
				int res=recv(i,rbuf,sizeof(rbuf),0);
				if(res==0){
					printf("客户端已下线\n");
					close(i);
 
					//移除关闭的文件描述符
					FD_CLR(i,&readfds);
					//更新文件描述符最大值
					for(int k=maxfd;k>=0;k--)
					{
						if(FD_ISSET(k,&readfds)){
							maxfd=k;
							break;
						}
					}
					continue;
				}
				printf("[%s:%d]:%s\n",inet_ntoa(cin_arr[i].sin_addr),ntohs(cin_arr[i].sin_port),rbuf);
 
 
				//回复消息
				strcat(rbuf," !!!");
				send(i,rbuf,strlen(rbuf),0);
			}
		}
 
	}
	//关闭套接字
	close(sfd);
 
	return 0;
}

客户端:

#include <myhead.h>
#define SER_IP "192.168.199.131"        //服务端IP
#define SER_PORT 8888                   //服务端端口号
 
#define CLI_IP "192.168.199.131"        //客户端IP
#define CLI_PORT 9999                   //客户端端口号
 
/*********************客户端**************************/
int main(int argc, const char *argv[])
{
	//1.创建用于通信的套接字
	int cfd=socket(AF_INET,SOCK_STREAM,0);
	if(cfd==-1){
		perror("socket error");
		return -1;
	}
	printf("cfd=%d\n",cfd);
	//2.绑定
	//填充地址信息结构体
	struct sockaddr_in cin;
	cin.sin_family=AF_INET;
	cin.sin_port=htons(CLI_PORT);
	cin.sin_addr.s_addr=inet_addr(CLI_IP);
 
	//绑定
	if(bind(cfd,(struct sockaddr *)&cin,sizeof(cin))==-1){
		perror("bind error");
		return -1;
	}
	printf("bind success\n");
 
	//3.连接服务器端
	//填充要连接的服务器地址信息结构体
	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(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1){
		perror("connect error");
		return -1;
	}
	printf("connect success\n");
 
	//poll完成客户端的并发操作
	struct pollfd pfd[2];
	pfd[0].fd=0;
	pfd[0].events=POLLIN;
 
	pfd[1].fd=cfd;
	pfd[1].events=POLLIN;
 
	//4.进行数据的收发
	char wbuf[128]="";
	while(1)
	{
		//监测文件描述符中是否有事件产生
		int res=poll(pfd,2,-1);
		if(res==-1){
			perror("poll error");
			return -1;
		}else if(res==0){
			printf("timeout\n");
			return -1;
		}
 
		//0号文件描述符的任务
		if(pfd[0].revents==POLLIN)
		{
			bzero(wbuf,sizeof(wbuf));
 
			printf("请输入>>>");
			fgets(wbuf,sizeof(wbuf),stdin);
			wbuf[strlen(wbuf)-1]='\0';
 
			send(cfd,wbuf,strlen(wbuf),0);
			printf("发送成功\n");
 
			if(strcmp(wbuf,"quit")==0){
				break;
			}
		}
		//recv函数的任务
		if(pfd[1].revents==POLLIN)
		{
			bzero(wbuf,sizeof(wbuf));
			recv(cfd,wbuf,sizeof(wbuf),0);
			printf("收到的消息为:%s\n",wbuf);
		}
	}
	//5.关闭套接字
	close(cfd);
	return 0;
}

 

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

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

相关文章

星瑞格数据库管理系统

一. 产品介绍 随着信息化的到来&#xff0c;数据安全成为保障信息化建设的一个关键问题&#xff1b;数据库作为信息化系统的基础软件其自身安全以及对数据的保障是至关重要。现阶段国内重要部门的信息系统存放着大量敏感数据&#xff0c;为了保障其数据的安全性&#xff0c;使用…

Mathcad tips_table相关

1. 可以插入表格&#xff0c;或者2. 从excel 文件导入 选择列 选择其中一行的数值

Batch Normalization和Layer Normalization和Group normalization

文章目录 前言一、Group normalization二、批量规范化(Batch Normalization)三、层规范化&#xff08;Layer Normalization&#xff09; 前言 批量规范化和层规范化在神经网络中的每个批次或每个层上进行规范化&#xff0c;而GroupNorm将特征分成多个组&#xff0c;并在每个组内…

HarmonyOS创建项目和应用—设置数据处理位置

项目和应用介绍 关于项目 项目是资源、应用的组织实体。资源包括服务器、数据库、存储&#xff0c;以及您的应用、终端用户的数据等。在您使用部分服务时&#xff0c;您是数据的控制者&#xff0c;数据将按照您设置的数据处理位置来存储在指定区域。 通常&#xff0c;您不需…

Mybatis实现分页查询数据(代码实操讲解)

在MyBatis中实现分页查询的常见方式有两种&#xff1a;使用MyBatis内置的分页插件如PageHelper&#xff0c;或者手动编写分页的SQL语句。下面我将为你提供两种方式的示例代码。 使用PageHelper分页插件 首先&#xff0c;确保你的项目中已经添加了PageHelper的依赖。在Maven项…

ZYNQ--关于一些SDK调试问题记录

Debug configuaration中没有debug applicaton 问题如下图&#xff1a; 解决方法&#xff1a; 在Target Setup中的Debug Type中选择如下即可 注意选完之后application中必须勾选运行内核&#xff0c;否则不运行main文件。

Java项目:36 springboot图书个性化推荐系统的设计与实现003

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 springboot003图书个性化推荐系统的设计与实现 管理员&#xff1a;首页、个人中心、学生管理、图书分类管理、图书信息管理、图书预约管理、退…

2195. 深海机器人问题(网络流,费用流,上下界可行流,网格图模型)

活动 - AcWing 深海资源考察探险队的潜艇将到达深海的海底进行科学考察。 潜艇内有多个深海机器人。 潜艇到达深海海底后&#xff0c;深海机器人将离开潜艇向预定目标移动。 深海机器人在移动中还必须沿途采集海底生物标本。 沿途生物标本由最先遇到它的深海机器人完成采…

vue3基础教程(2)——创建vue3+vite项目

博主个人微信小程序已经上线&#xff1a;【中二少年工具箱】。欢迎搜索试用 正文开始 专栏简介1. 前言2.node版本检测3.创建vue项目 专栏简介 本系列文章由浅入深&#xff0c;从基础知识到实战开发&#xff0c;非常适合入门同学。 零基础读者也能成功由本系列文章入门&#x…

循环队列:一道使数据结构萌新知道什么是“愁滋味“的题目

这破题目肝了我一天半才搞明白,也正是因为这道题目,我才豁然明白了李煜所说的"剪不断,理还乱...别是一般滋味在心头"到底是什么"滋味".在完全搞明白之前,真的是放有放不下,理也理不清... 但是理解之后你会发现,嘛い---,也就那么个回事嘛O(∩_∩)O 目录 1…

【DreamTalk】源码部署

安装 # 下载源码 git clone https://github.com/ali-vilab/dreamtalk cd dreamtalkconda create -n dreamtalk python3.10 conda activate dreamtalkconda install -c conda-forge yacs0.1.8 conda install -c conda-forge numpy1.21.5 conda install -c conda-forge av10.0.0…

如何使用宝塔面板部署MySQL数据库,并结合内网穿透实现固定公网地址远程连接

文章目录 前言1.Mysql服务安装2.创建数据库3.安装cpolar3.1 开放局域网端口3.2 创建HTTP隧道 4.远程连接5.固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 宝塔面板的简易操作性,使得运维难度降低,简化了Linux命令行进行繁琐的配置,下面简单几…

为什么Spring Cloud 应用程序中,应用程序的加载配置必须写在bootstrap.yaml这个配置文件中,是在哪里规定的?

在 Spring Cloud 应用程序中&#xff0c;bootstrap.yaml&#xff08;或bootstrap.properties&#xff09;的使用并非强制性的&#xff0c;但它扮演着一个特定的角色&#xff0c;主要是因为 Spring Cloud 的设计和工作流程。 背景和设计 Spring Cloud 构建在 Spring Boot 之上…

STM32FreeRTOS-事件组1(STM32Cube高效开发教程)

文章目录 一、事件组的原理和功能1、事件组与队列信号量特点2、事件组存储结构3、事件组运行原理 二、事件组部分函数1、xEventGroupCreate()创建事件组函数2、xEventGroupSetBits&#xff08;&#xff09;事件组置位函数3、xEventGroupSetBitsFromISR&#xff08;&#xff09;…

Geeker Admin添加若以分离版本的后台作为后台

添加验证码 下载若依赖前后端分离版本&#xff0c;配置好自己数据库&#xff0c;redis连接地址 登录添加验证码 配置自己的若依后端连接地址 添加验证码请求方法 登录页面登录输入框添加验证码&#xff0c;uuid,调用的验证码刷新方法 注意&#xff1a;这里要用响应式定义验证…

外汇天眼:蓝莓市场终止所有MT4/MT5专业公司业务

总部位于澳大利亚的零售外汇和差价合约经纪商蓝莓市场宣布&#xff0c;已终止其数据和平台服务产品&#xff0c;该产品旨在通过利用其基础设施为专业公司行业提供服务。 蓝莓市场表示&#xff0c;已经对其数据和平台服务产品“落下帷幕”&#xff0c;与所有专业交易公司包括MyF…

分类问题经典算法 | 二分类问题 | Logistic回归:梯度下降

目录 一. 损失函数1. 交叉熵损失函数2. 梯度下降 一. 损失函数 Logistic回归算法公式推导篇中&#xff0c;我们通过对似然函数求对数&#xff0c;得到 l ( θ ) l(\theta ) l(θ)&#xff1a; l ( θ ) l n [ L ( θ ) ] ∑ i 1 M { y ( i ) l n [ h θ ( x ( i ) ) ] ( …

Jekins 自启动Java应用的Shell笔记

背景 最近在研究jdk 的jvisualvm 对JVM服务远程监控时&#xff0c;意外的与jekins接轨了。公司使用jekins自动从Git上获得源码&#xff0c;打包后传到测试服务器并启动jar包&#xff0c;实现自动部署&#xff0c;而我需要做的是在测试服务器启动jar包时添加几个我设置的命令&am…

【YOLO v5 v7 v8 v9小目标改进】DWRSeg:优化的多尺度处理,传统的深度学习模型可能在不同尺度的特征提取上存在冗余

DWRSeg&#xff1a;优化的多尺度处理&#xff0c;传统的深度学习模型可能在不同尺度的特征提取上存在冗余 提出背景问题&#xff1a;实时语义分割需要快速且准确地处理图像数据&#xff0c;提取出有意义的特征来识别不同的对象。 小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔…

超级副业SOP,各行各业,太全了!

最近收集到一份资料&#xff0c;包含了几乎各行各业的SOP&#xff0c;实在是太全了&#xff0c;这里准备分享给大家 这里可能有一些朋友还不知道&#xff0c;SOP是个什么东西呢 百度说法&#xff1a;所谓SOP&#xff0c;是 Standard Operating Procedure三个单词中首字母的大写…