网络通信day5作业

1>    使用select完成TCP客户端程序

客户端:

#include<myhead.h>

#define FPORT 9999
#define FIP "192.168.125.130"

#define KPORT 6666
#define KIP "192.168.125.130"

int main(int argc, const char *argv[])
{
	//创建套接字文件描述符
	int cfd = 0;
	if((cfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
	{
		perror("socket error");
		return -1;
	}
	//允许重复引用
	int reuse = 1;
	if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1)
	{
		perror("setsockopt error");
		return -1;
	}

	//绑定客服端
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(KPORT);
	sin.sin_addr.s_addr = inet_addr(KIP);
	if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
	{
		perror("bind error");
		return -1;
	}

	//连接服务器
	struct sockaddr_in cin;
	cin.sin_family = AF_INET;
	cin.sin_port = htons(FPORT);
	cin.sin_addr.s_addr = inet_addr(FIP);

	if(connect(cfd,(struct sockaddr*)&cin,sizeof(cin)) == -1)
	{
		perror("connect");
		return -1;
	}

	//定义检测文件描述符的集合
	fd_set readfd;

	//清空集合
	FD_ZERO(&readfd);

	//将cfd和0加入集合
	FD_SET(cfd,&readfd);
	FD_SET(0,&readfd);

	char buf[128] = "";
	int res = -1;

	fd_set tempfd;

	while(1)
	{
		tempfd = readfd;
		res = select(cfd+1,&tempfd,NULL,NULL,NULL);
		if(res < 0)
		{
			perror("select error");
			return -1;
		}else if(res == 0)
		{
			printf("time out\n");
			return -1;
		}
		//下面为处理的处理描述符
		if(FD_ISSET(0,&tempfd))
		{
			bzero(buf,sizeof(buf));

			fgets(buf,sizeof(buf),stdin);
			buf[strlen(buf)-1]=0;

			send(cfd,buf,sizeof(buf),0);
			printf("客服端输入为%s\n",buf);
		}



		if(FD_ISSET(cfd,&tempfd))
		{
			bzero(buf,sizeof(buf));

			int res = recv(cfd,buf,sizeof(buf),0);
			if(res == 0)
			{
				printf("服务器下线\n");
				break;
			}
			printf("服务器发来的消息为%s\n",buf);
		}
	}

	close(cfd);


	return 0;
}

服务器:

#include<myhead.h>
#define PORT 9999
#define IP "192.168.125.130"

int main(int argc, const char *argv[])
{
	int sfd = -1;
	if((sfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
	{
		perror("socket");
		return -1;
	}
	
	int reuse = 1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1)
	{
		perror("setsockopt error");
		return -1;
	}

	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;
	}

	if(listen(sfd,128)  == -1)
	{
		perror("listen error");
		return -1;
	}

	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);

	int newfd = -1;
	char buf[128] = "";

	fd_set readfds;

	FD_ZERO(&readfds);

	FD_SET(sfd,&readfds);
	FD_SET(0,&readfds);

	int res = 0;
	fd_set tempfds;

	int maxfd = sfd;

	char rbuf[128]="";

	struct sockaddr_in arr_cin[1024];

	while(1)
	{
		tempfds = readfds;

		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 index=0;index<=maxfd;index++)
		{
			if(!FD_ISSET(index,&tempfds))
			{
				continue;
			}

			if(index == sfd)
			{
				if((newfd = accept(sfd,(struct sockaddr*)&cin,&socklen)) == -1)
				{
					perror("accept");
					return -1;
				}
				arr_cin[newfd] =cin;
				printf("[%s:%d]链接成功,newfd = %d\n\n",inet_ntoa(arr_cin[newfd].sin_addr),ntohs(arr_cin[newfd].sin_port),newfd);

				FD_SET(newfd,&readfds);
				if(newfd > maxfd)
				{
					maxfd = newfd;
				}
			}else if(index == 0)
			{
				scanf("%s",buf);
				printf("%s\n",buf);
			}else
			{
				bzero(rbuf,sizeof(rbuf));

				int res = recv(index,rbuf,sizeof(rbuf),0);
				if(res == 0)
				{
					printf("客户端下线\n");

					close(index);

					FD_CLR(index,&readfds);

					for(int i =maxfd;i>0;i--)
					{
						if(FD_ISSET(i,&readfds))
						{
							maxfd = i;
							break;
						}
					}
					continue;
				}
				printf("[%s:%d] :%s\n",inet_ntoa(arr_cin[index].sin_addr),ntohs(arr_cin[index].sin_port),rbuf);
				strcat(rbuf,"*_*");
				send(index,rbuf,sizeof(rbuf),0);
			}
		}
	}

	close(sfd);

	return 0;
}

效果图:


2>    使用poll完成TCP并发服务器

客户端:

#include<myhead.h>
#define SERPORT 9999
#define SERIP "192.168.125.130"

#define CLIPORT 6666
#define CLIIP "192.168.125.130"


int main(int argc, const char *argv[])
{
	int cfd = -1;
	if((cfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
	{
		perror("socket error");
		return -1;
	}
	printf("cfd = %d\n",cfd);

	int reuse = 1;
	if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1)
	{
		perror("setsockopt error");
		return -1;
	}
	
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(CLIPORT);
	sin.sin_addr.s_addr = inet_addr(CLIIP);

	if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
	{
		perror("bind error");
		return -1;
	}

	struct sockaddr_in cin;
	cin.sin_family = AF_INET;
	cin.sin_port = htons(SERPORT);
	cin.sin_addr.s_addr = inet_addr(SERIP);

	if(connect(cfd,(struct sockaddr*)&cin,sizeof(cin)) == -1)
	{
		perror("connect error");
		return -1;
	}

	struct pollfd fds[2];
	fds[0].fd = 0;
	fds[0].events = POLLIN;

	fds[1].fd = cfd;
	fds[1].events = POLLIN;

	int res = -1;

	char wbuf[128] = "";
	while(1)
	{
		res = poll(fds,2,-1);
		if(res < 0)
		{
			perror("poll error");
			return -1;
		}else if(res == 0)
		{
			printf("time out \n");
			return -1;
		}
		if(fds[0].revents == POLLIN)
		{
			bzero(wbuf,sizeof(wbuf));

			fgets(wbuf,sizeof(wbuf),stdin);
			wbuf[strlen(wbuf)-1]=0;

			send(cfd,wbuf,sizeof(wbuf),0);

		}

		if(fds[1].revents == POLLIN)
		{
			bzero(wbuf,sizeof(wbuf));

			int res = recv(cfd,wbuf,sizeof(wbuf),0);
			if(res == 0)
			{
				printf("服务器已下线\n");
				break;
			}
			printf("[%s:%d]:%s\n",SERIP,SERPORT,wbuf);
		}
	}
	close(cfd);






	return 0;
}

服务器:

#include<myhead.h>

#define PORT 9999
#define IP "192.168.125.130"


int main(int argc, const char *argv[])
{
	//定义套接字文件描述符
	int cfd = -1;
	if((cfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
	{
		perror("socket error");
		return -1;
	}
	//端口快速重用
	int reuse = 1;
	if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1)
	{
		perror("setsockopt error");
		return -1;
	}
	//绑定服务器套接字信息并连接
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);

	if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
	{
		perror("bind error");
		return -1;
	}
	//设置为监听状态
	if(listen(cfd,128) == -1)
	{
		perror("listen error");
		return -1;
	}

	//要检测的文件描述符集合对应的数组
	struct pollfd fds[1024];
	//定义客户端信息
	struct sockaddr_in add_cin[1024];

	//标准0
	fds[0].fd = 0;
	fds[0].events = POLLIN;

	//标准cfd
	fds[cfd].fd = cfd;
	fds[cfd].events = POLLIN;

	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);


	int newfd = -1;
	int res = -1;
	int size = 4;//初始成员个数
	char buf[128]="";
	while(1)
	{
		res = poll(fds,size,-1);
		if(res == -1)
		{
			perror("poll error");
			return -1;
		}else if(res == 0)
		{
			printf("time out\n");
			return -1;
		}

		for(int index=0;index<1024;index++)
		{
			if(fds[index].revents != POLLIN)
			{
				continue;
			}

			if(fds[cfd].revents == POLLIN)
			//if((fds[index].revents == POLLIN)&&(fds[index].fd == cfd))
			{
				//到此下面为操作文件描述符
				//设置为等待连接状态

				if((newfd = accept(cfd,(struct sockaddr*)&cin,&socklen)) == -1)
				{
					perror("accept error");
					return -1;
				}
				//客户端加入数组
				add_cin[newfd]=cin;
				fds[size].fd = newfd;
				fds[size].events = POLLIN;
				size++;
				//printf("连接成功\n");
				printf("[%s,%d]连接成功,newfd=%d\n",inet_ntoa(add_cin[newfd].\
							sin_addr),ntohs(add_cin[newfd].sin_port),newfd);

			}
			else if((fds[index].revents == POLLIN)&&fds[index].fd == 0)
			{
				bzero(buf,sizeof(buf));
				//终端输入
				fgets(buf,sizeof(buf),stdin);
				buf[strlen(buf)-1] = 0;

				printf("服务器输入为%s\n",buf);

			}
			else 
			{
				bzero(buf,sizeof(buf));

				int resa = recv(fds[index].fd,buf,sizeof(buf),0);
				if(resa == 0)
				{
					printf("客户端下线\n");
					close(fds[index].fd);
					fds[index] = fds[size];
					size--;
					continue;
				}
				printf("[%s,%d]发送%s\n",inet_ntoa(add_cin[newfd].sin_addr),\
						ntohs(add_cin[newfd].sin_port),buf);
				strcat(buf,"*_*");
				send(fds[index].fd,buf,sizeof(buf),0);
			}
		}
	}


	return 0;
}

 服务器:

#include<myhead.h>

#define PORT 9999
#define IP "192.168.125.130"


int main(int argc, const char *argv[])
{
	//定义套接字文件描述符
	int cfd = -1;
	if((cfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
	{
		perror("socket error");
		return -1;
	}
	//端口快速重用
	int reuse = 1;
	if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1)
	{
		perror("setsockopt error");
		return -1;
	}
	//绑定服务器套接字信息并连接
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);

	if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
	{
		perror("bind error");
		return -1;
	}
	//设置为监听状态
	if(listen(cfd,128) == -1)
	{
		perror("listen error");
		return -1;
	}

	//要检测的文件描述符集合对应的数组
	struct pollfd fds[1024];
	//定义客户端信息
	struct sockaddr_in add_cin[1024];

	//标准0
	fds[0].fd = 0;
	fds[0].events = POLLIN;

	//标准cfd
	fds[cfd].fd = cfd;
	fds[cfd].events = POLLIN;

	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);


	int newfd = -1;
	int res = -1;
	int size = 4;//初始成员个数
	char buf[128]="";
	while(1)
	{
		res = poll(fds,size,-1);
		if(res == -1)
		{
			perror("poll error");
			return -1;
		}else if(res == 0)
		{
			printf("time out\n");
			return -1;
		}

		for(int index=0;index<1024;index++)
		{
			if(fds[index].revents != POLLIN)
			{
				continue;
			}

			if(fds[cfd].revents == POLLIN)
			{
				//到此下面为操作文件描述符
				//设置为等待连接状态

				if((newfd = accept(cfd,(struct sockaddr*)&cin,&socklen)) == -1)
				{
					perror("accept error");
					return -1;
				}
				//客户端加入数组
				add_cin[newfd]=cin;
				fds[newfd].fd = newfd;
				fds[newfd].events = POLLIN;
				size++;
				//printf("连接成功\n");
				printf("[%s,%d]连接成功,newfd=%d\n",inet_ntoa(add_cin[newfd].\
							sin_addr),ntohs(add_cin[newfd].sin_port),newfd);

			}
			else if((fds[index].revents == POLLIN)&&fds[index].fd == 0)
			{
				bzero(buf,sizeof(buf));
				//终端输入
				fgets(buf,sizeof(buf),stdin);
				buf[strlen(buf)-1] = 0;

				printf("服务器输入为%s\n",buf);

			}
			else 
			{
				bzero(buf,sizeof(buf));

				int resa = recv(fds[index].fd,buf,sizeof(buf),0);
				if(resa == 0)
				{
					printf("客户端下线\n");
					close(fds[index].fd);
					//fds[index] = fds[size];
					//size--;
					continue;
				}
				printf("[%s,%d]发送%s\n",inet_ntoa(add_cin[newfd].sin_addr),\
						ntohs(add_cin[newfd].sin_port),buf);
				strcat(buf,"*_*");
				send(fds[index].fd,buf,sizeof(buf),0);
			}
		}
	}


	return 0;
}

效果图:

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

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

相关文章

IP子网划分【专题突破】

1、IP地址基础 IPv4地址是32位&#xff0c;采用点分十进制方式表示&#xff0c;其次必须掌握二进制的转换。 IPv6地址是128位&#xff0c;采用冒号分隔的十六进制表示方法。 2、IP地址的分类 RFC1918规定的私有地址 A类地址范围&#xff1a;10.0.0.0-10.255.255.255(1个A类…

二叉树题目:输出二叉树

文章目录 题目标题和出处难度题目描述要求示例数据范围 前言解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;输出二叉树 出处&#xff1a;655. 输出二叉树 难度 6 级 题目描述 要求 给定二叉树的根结点 root \textt…

oracle定位造成卡顿的SQL语句

先查询阻塞的会话号 select event,machine,sql_id,program,blocking_session from dba_hist_active_sess_history where SAMPLE_TIME between TO_TIMESTAMP (2021-08-25 15:25:00, YYYY-MM-DD HH24:MI:SS) and TO_TIMESTAMP (2021-08-25 15:30:00, YYYY-MM-DD HH24:MI:SS) and …

PolarDB-X、OceanBase、CockroachDB、TiDB二级索引写入性能测评

为什么要做这个测试 二级索引是关系型数据库相较于NoSQL数据库的一个关键差异。二级索引必须是强一致的&#xff0c;因此索引的写入需要与主键的写入放在一个事务当中&#xff0c;事务的性能是二级索引性能的基础。 目前市面上的分布式数据库中&#xff0c;从使用体验的角度看…

PCL点云处理之点云置平(拟合平面绕中心旋转到绝对水平)(二百二十七)

PCL点云处理之点云置平(绕中心旋转到绝对水平)(二百二十七) 一、什么是点云置平二、算法流程三、算法实现一、什么是点云置平 有时候,我们处理的点云平面并非位于水平面,而是位于某个任一三维平面上,而大多数算法又只能在水平面处理,或者水平面的点云处理是相对更简单…

互操作性(Interoperability)如何影响着机器学习的发展?

互操作性&#xff08;Interoperability&#xff09;&#xff0c;也称为互用性&#xff0c;即两个系统之间有效沟通的能力&#xff0c;是机器学习未来发展中的关键因素。对于银行业、医疗和其他生活服务行业&#xff0c;我们期望那些用于信息交换的平台可以在我们需要时无缝沟通…

弧形导轨的加工方式有哪些?

弧形导轨常用于流水线的加工或是机械化工业的生产中&#xff0c;运动的导轨呈弧形&#xff0c;可以连接起来形成其它形态也可以是单一的&#xff0c;使用弧形导轨后是可以提高工作效率的&#xff0c;比传统的生产模式要更加快速&#xff0c;所以在很多工厂或生产车间都有它的身…

前端开发新趋势:Web3 与虚拟现实的技术融合

在当今互联网技术日新月异的时代&#xff0c;Web技术也在不断地发展和变革。从前端开发的角度来看&#xff0c;新技术的涌现和旧技术的迭代让前端开发者们面临着前所未有的挑战和机遇。Web3 与虚拟现实&#xff08;VR&#xff09;的技术融合&#xff0c;正是当前前端开发领域的…

Spring Boot学习随笔- 文件上传和下载(在线打卡、附件下载、MultipartFile)

学习视频&#xff1a;【编程不良人】2021年SpringBoot最新最全教程 第十二章、文件上传、下载 文件上传 文件上传是指将文件从客户端计算机传输到服务器的过程。 上传思路 前端的上传页面&#xff1a;提交方式必须为post&#xff0c;enctype属性必须为multipart/form-data开发…

springboot云HIS医院信息管理系统源码

通过云HIS平台,可以减少医院投资,无需自建机房和系统,快速实现信息化服务。系统升级及日常维护服务有云平台提供,无需配备专业IT维护人员进行系统维护。 一、his系统和云his系统的区别 His系统和云his系统是两种不同的计算平台&#xff0c;它们在技术架构上存在很大的差异。下…

进阶之路:高级Spring整合技术解析

Spring整合 1.1 Spring整合Mybatis思路分析1.1.1 环境准备步骤1:准备数据库表步骤2:创建项目导入jar包步骤3:根据表创建模型类步骤4:创建Dao接口步骤5:创建Service接口和实现类步骤6:添加jdbc.properties文件步骤7:添加Mybatis核心配置文件步骤8:编写应用程序步骤9:运行程序 1.…

​Halcon机器视觉软件学习指南

引言 Halcon是由德国MVTec软件公司开发的一款领先的机器视觉软件&#xff0c;广泛应用于工业检测、图像分析、医疗图像处理等领域。对于大学生和初学者而言&#xff0c;学习Halcon不仅能够提升技术层面的能力&#xff0c;还能够增强未来的就业竞争力。本文将为您提供一个系统的…

东莞城市更新区域关注程度分析tiff数据,城市规划必备

基本信息. 数据名称: 东莞市城市更新区域关注程度分析数据 数据格式: tiff 时间版本&#xff1a;2022年 数据几何类型: 无 数据精度&#xff1a;区县 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据

【Anaconda】重装source 不生效,command not found 解决

事情是这样的&#xff0c;在Linux上安装anaconda的时候&#xff0c;由于一直需要同意其协议&#xff0c;因此在按enter 下一行时候出现过好几次翻过了&#xff0c;导致直接等于no了。&#xff08;实际上&#xff0c;按字母d可以实现翻页的功能&#xff0c;不需要一直enter了&am…

Ubuntu 常用命令之 awk 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 AWK是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具。在Ubuntu系统下&#xff0c;AWK命令主要用于数据处理和生成报告。 AWK命令的参数主要有 -F&#xff1a;指定输入文件分隔符&#xff0c;FS变量就是指定输入字…

百年东芝“瞄准”汽车「芯」机遇

在汽车“新四化”大变革的驱动下&#xff0c;汽车半导体市场进入需求暴涨的新周期。 “智能电动汽车所需要的半导体种类和数量正在急剧增加。” 东芝电子分立器件应用技术部经理成栋表示&#xff0c;东芝电子正在加大汽车半导体市场的布局&#xff0c;从而满足汽车电动化、智能…

老师如何提高教育质量的问题

教育质量是学校教育的核心&#xff0c;也是衡量一个老师工作成果的重要标准。作为老师&#xff0c;我们应该时刻关注如何提高教育质量&#xff0c;以更好地促进学生的全面发展。 一、注重备课 备课是提高教育质量的基础。老师应该认真研究教材&#xff0c;了解学生的实际情况&…

ansible脚本-Playbook(一)

Playbook组成部分&#xff1a; task 任务&#xff1a;包含目标主机上执行的操作&#xff0c;使用模块定义这些操作&#xff0c;每个任务都是一个模块的调用Variables变量&#xff1a;存储和传递数据&#xff0c;变量可以自定义&#xff0c;可以在playbook当中定义为全局变量&a…

数据管理平台Splunk Enterprise本地部署结合内网穿透实现远程访问

文章目录 前言1. 搭建Splunk Enterprise2. windows 安装 cpolar3. 创建Splunk Enterprise公网访问地址4. 远程访问Splunk Enterprise服务5. 固定远程地址 前言 Splunk Enterprise是一个强大的机器数据管理平台&#xff0c;可帮助客户分析和搜索数据&#xff0c;以及可视化数据…

NCV8460ADR2G在汽车和工业应用中高压侧驱动如何破?

NCV8460ADR2G是一款完全保护的高压侧驱动器&#xff0c;可用于开关各种负载&#xff0c;如灯泡、电磁阀和其他致动器。该器件可以通过有源电流限制和高温关断针对过载情况进行内部保护。 诊断状态输出引脚提供了高温以及开关状态开路负载情况的数字故障指示。 特性&#xff1a;…
最新文章