day 5 select服务器和客户端

2023-05-16

select客户端代码:

#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/select.h>
#include<sys/time.h>


#define ERR_MSG(msg) do{\
	fprintf(stderr,"line:%d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.8.53"  //本机ip
#define PORT 6667
int main(int argc, const char *argv[])
{
	//创建流式套接字
	int cfd =socket(AF_INET,SOCK_STREAM,0);
	if(cfd<0)
	{
		ERR_MSG("scoket");
		return -1;
	}
	printf("cfd=%d\n",cfd);

	//允许端口快速重用
	int reuse =1;
	if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	printf("允许端口快速重用成功\n");
	//非必须绑定
	
	//填充地址信息结构体
	//真实的地址信息结构体根据地址族指定 AF_INET:man 7 ip
	struct sockaddr_in sin;
	sin.sin_family =AF_INET;  //必须填AF_INET
	sin.sin_port  =htons(PORT); //端口号 1024~49151
	sin.sin_addr.s_addr=inet_addr(IP); //本机ip ifconfig
	

	
	//connect 连接服务器
	
	if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("connect");
		return -1;
	}
	printf("connect success __%d__\n",__LINE__);
	
	//创建一个读集合
	fd_set readfds,tmpfds;

	FD_ZERO(&readfds);
	FD_SET(0,&readfds);
	FD_SET(cfd,&readfds);
	FD_ZERO(&tmpfds);	

	char buf[128]="";
	ssize_t res=0;
	int s_res=-1;
	while(1)
	{
		tmpfds=readfds;
		s_res=select(cfd+1,&tmpfds,NULL,NULL,NULL);
		if(s_res<0)
		{
			ERR_MSG("select");
			return -1;
		}
		else if(0==s_res)
		{
			printf("time out..\n");
			return -1;
		}
		if((FD_ISSET(0,&tmpfds))) //读集合中存在0
		{
			//发送 从终端获取数据
			bzero(buf,sizeof(buf));
			printf("请输入>>>");
			fgets(buf,sizeof(buf),stdin);
			buf[strlen(buf)-1]=0;

			if(send(cfd,buf,sizeof(buf),0)<0)
			{
				ERR_MSG("send");
				return -1;
			}
			printf("发送成功\n");
		}
        if((FD_ISSET(cfd,&tmpfds)))
		{
			bzero(buf,sizeof(buf));
			//接收
			res= read(cfd,buf,sizeof(buf));
			//res= recv(cfd,buf,sizeof(buf),0);
			if(res<0)
			{
				ERR_MSG("recv");
				return -1;
			}
			else if(0==res)
			{
				printf("cfd=%d 服务器下线__%d__\n",cfd,__LINE__);
				break;
			}
			printf("cfd=%d :%s__%d__\n",cfd,buf,__LINE__);
		}
	}

	//关闭
	close(cfd);

	return 0;
}

select服务器代码:

#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/select.h>
#include<sys/time.h>


#define ERR_MSG(msg) do{\
	fprintf(stderr,"line:%d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.8.53"  //本机ip
#define PORT 6667
int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd =socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("scoket");
		return -1;
	}
	printf("sfd=%d\n",sfd);

	//允许端口快速重用
	int reuse =1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	printf("允许端口快速重用成功\n");
	//填充地址信息结构体
	//真实的地址信息结构体根据地址族指定 AF_INET:man 7 ip
	struct sockaddr_in sin;
	sin.sin_family =AF_INET;  //必须填AF_INET
	sin.sin_port  =htons(PORT); //端口号 1024~49151
	sin.sin_addr.s_addr=inet_addr(IP); //本机ip ifconfig
	

	//将IP和端口绑定到套字节上
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind success __%d__\n",__LINE__);

	//将套接字设置为被动监听状态,监听是否有客户端连接成功
	if(listen(sfd,128)<0)
	{
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success __%d__\n",__LINE__);

	//设置一个读集合
	fd_set readfds,tmpfds;  //vi -t fd_set ,集合中只有一个成员是长整形数组

	//由于readfds中需要防止要检测的文件描述符,所以不能让他是随机值
	//所以需要将readfds清空
	FD_ZERO(&readfds);
	FD_ZERO(&tmpfds);
	
	//将需要的文件描述符添加到集合中
	FD_SET(0,&readfds);
	FD_SET(sfd,&readfds);

	int maxfd =sfd; //最大文件描述符
	
	char buf[128]="";
	ssize_t res=0;
	struct sockaddr_in cin;  //存储连接成功的客户端地址信息
	socklen_t addrlen =sizeof(cin);

	struct sockaddr_in saveCin[1024-4];//另存客户端地址信息,0,1,2,sfd不可能有对应的客户端
	int newfd =-1;
	int s_res=0;
	while(1)
	{
		tmpfds =readfds;
		s_res=select(maxfd+1,&tmpfds,NULL,NULL,NULL);
		if(s_res<0)
		{
			ERR_MSG("select");
			return -1;
		}
		else if(0==s_res)
		{
			printf("time out...\n");
			return -1;
		}
		//能运行到当前位置,则代表有文件描述符准备就绪
		//走触发事件的文件描述符对应的处理函数

		//当集合中有文件描述符准备就绪了,集合中就会只保留产生事件的文件描述符
		//当0准备就绪,集合中会保留0
		//当sfd准备就绪,集合中只会保留sfd
		//当0和sfd都准备就绪,集合中会保留0和sfd
		//所以只需要判断集合中剩下哪个文件描述符,走对应函数即可
		for(int i=0;i<=maxfd;i++)
		{
			if(!FD_ISSET(i,&tmpfds))
			{
				continue;
			}
			if(0==i)
			{
				printf("触发键盘输入事件>>>");
				int sndfd=-1;
				res =scanf("%d %s",&sndfd,buf);
				while(getchar()!=10);
				if(res!=2)
				{
					fprintf(stderr,"请输入正确格式:int string\n");
					continue;
				}
				//能运行到当前位置,则代表输入的格式整数
				if(sndfd<=sfd||sndfd>=1024||!FD_ISSET(sndfd,&readfds))
				{
					fprintf(stderr,"sndfd=%d 文件描述符错误\n",sndfd);
					continue;
				}
				if(send(sndfd,buf,sizeof(buf),0)<0)
				{
					ERR_MSG("send");
					return -1;
				}
			}
			else if(sfd==i)
			{
				printf("触发客户端连接事件>>>");
				fflush(stdout);
				newfd =accept(sfd,(struct sockaddr*)&cin,&addrlen);
				if(newfd<0)
				{
					ERR_MSG("accept");
					return -1;
				}
				printf("[%s:%d] newfd=%d 连接成功__%d__\n",\
						inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,__LINE__);

				saveCin[newfd-4]=cin;
				//将newfd添加到读合集中
				FD_SET(newfd,&readfds);

				//更新maxfd
				maxfd =maxfd>newfd?maxfd:newfd;
			}
			else
			{
				bzero(buf,sizeof(buf));
				//接收
				res= recv(i,buf,sizeof(buf),0);
				if(res<0)
				{
					ERR_MSG("recv");
					return -1;
				}
				else if(0==res)
				{
					printf("[%s:%d] newfd=%d 客户端下线__%d__\n",\
							inet_ntoa(saveCin[i-4].sin_addr),ntohs(saveCin[i-4].sin_port),i,__LINE__);
					//关闭文件描述符
					close(i);
					//从集合中剔除该文件描述符
					FD_CLR(i,&readfds);

					//更新maxfd,
					//从目前最大的文件描述符往小的判断,直到判断带在集合中
					//那么该文件描述符就是最大的
					int j=0;
					for(j=maxfd;j>=0;j--)
					{
						if(FD_ISSET(j,&readfds))
						{
							maxfd=j;
							break;
						}
					}
					if(j<0)  //若集合中没有要检测的文件描述符了,则让maxfd=-1;
				    	maxfd =-1;

					continue;
				}
				printf("[%s:%d] newfd=%d :%s__%d__\n",\
						inet_ntoa(saveCin[i-4].sin_addr),ntohs(saveCin[i-4].sin_port),i,buf,__LINE__);	
				//发送
				strcat(buf,"*_*");
				if(send(i,buf,sizeof(buf),0)<0)
				{
					ERR_MSG("send");
					return -1;
				}
				printf("发送成功\n");

			}

		}
	}

	//关闭
	close(sfd);
	return 0;
}

运行结果:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

day 5 select服务器和客户端 的相关文章

  • 使用 xmlagg 函数的 SQL 多个 SELECT 查询 - 未按所需方式提取数据

    我在Oracle中的数据是这样的 NAME DEP VALUE ID DEP Amy 1 AA1234 Bob 2 BB4321 Clara 1 CC5678 Clara 2 CC7890 John 1 JJ6543 John 2 JJ78
  • 即使具有 SELECT 权限也无法选择表

    我有两个用户 USER1 and USER2 USER1有特权create table and USER2没有这个特权 USER1创建了一个名为EMPLOYEE并授予select该表的特权USER2 使用 USER1 凭据 1 创建表 CR
  • 当想要批量返回x个元素组时MySQL选择查询

    如何通过单个查询批量返回选择结果 这应该是一个直接的复合选择 下面是一个示例表和一个简单的查询 它将通过当前使用在最终现实世界过程中无法工作的临时数字列来生成所需的结果 仅涉及两个关键列 ip addresses and oid addre
  • Oracle 和 SQL Server 保留关键字

    我需要 Oracle Database 10g 和 SQL Server 2008 保留关键字的列表 我的应用程序执行 DDL 语句 因此我需要根据保留字验证输入的表名 列名等 我知道我可以复制并粘贴网站上的文字 甲骨文10g http d
  • 尝试将 NOT EXIST 转换为 COUNT

    所以我知道如何使用进行查询NOT EXIST 但我似乎找不到等效的使用COUNT反而 结构 player playerID integer playerName string team teamID integer teamName str
  • 单击标签未打开选择

    我一直以为 点击label将或多或少地 触发 相应表单元素的点击 然而 这似乎不起作用select 选择字段上的鼠标按下 动画有效 但选择未打开 我试过这个
  • Mysql 选择行的总和

    我有一张包含以下信息的表 id Item ID stock package id amount price 0 775 1 16 0 22 1 758 2 10 0 28 2 775 3 10 0 30 3 774 4 10 0 25 4
  • mySQL 当 field=0 时返回所有行

    我正在做一些测试 当我查询一个表时 令人惊讶的是 查询SELECT FROM table WHERE email 0返回表中的所有行 该表没有 0 值 并且填充了常规电子邮件 为什么会出现这种情况 这可能会导致严重的安全问题 有没有办法在不
  • 简单的 MySQL 语法错误 [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在运行以下代码 但找不到错误是什么 谁能建议我应该检查什么 result mysql query SELECT FROM ta
  • 如何检查日期范围是否存在

    正如你从标题中可能注意到的 我的问题很难表达 但有一个问题 我有包含一些数据的 MySQL 表 在注册表中 我必须指定预订开始和结束时间 如何查询指定时间是否已登记预订 例如 我不应该能够添加从 13 20 开始到 15 00 结束的新预订
  • 在 PHP 中对逗号分隔值列表运行选择

    我在数据库上运行选择查询时遇到一些问题 一些数据以逗号分隔值的列表形式保存 例如 Table example tbl Id People Children 1 1 2 3 8 10 3 2 7 6 12 18 19 2 我正在尝试运行的示例
  • select.select() 没有捕获套接字上的异常条件?

    Python 2 7 Windows XP 我有一个向客户端发送消息的服务器 我使用 select 模块来检查套接字是否准备好接收 以及捕获异常情况 我的印象是 如果客户端关闭了套接字 select 会在异常条件套接字列表中返回所述套接字
  • 如何使用 MS SQL 2008 获取数据库中的表列表?

    我想验证数据库中是否存在表 如果不存在 则创建它 如何获取当前数据库中所有表的列表 我可以使用这样的 SELECT 获取数据库列表 SELECT FROM sys databases 剩下的就是创建该表 如果该表不存在 我还尝试与数据库同时
  • jQuery,选择具有属性的最近兄弟(下一个或上一个)

    我有一个类似于下面标记的选择下拉列表
  • 将 HTML 选择元素转换为带有子菜单的树

    我想让一个选择元素有一个树形的子菜单 我希望它是这样的 source colinear com http www colinear com rmenu gif 有没有一个 jQuery 插件可以将 select 元素变成这种东西 这里有树插
  • 为什么 peewee 将“id”列包含到 mysql select 查询中?

    我正在尝试学习如何将 peewee 与 mysql 一起使用 我在 mysql 服务器上有一个现有数据库和一个现有表 该表当前为空 我现在正在测试 gt gt gt db MySQLDatabase nhl user root passwd
  • 为什么这个简单的 MySQL 查询不返回该行?

    我在表中有一行users与用户名test 但由于某种原因 此查询返回空结果集 SELECT id FROM users WHERE username test AND id null 但是 如果我删除 id null段 查询返回结果id 1
  • MySQL Select 查询 - 仅获取值的前 10 个字符

    好的 这就是问题所在 我有一个包含一些列的表 主题 是其中一列 无论 主题 字段包含一个包含 100 个字母的字符串 我都需要从 主题 字段获取前 10 个字母 例如 Table tbl 列 id subject value SQL查询 S
  • 当Where子句中的术语不在数据库中时,如何从MySQL数据库返回0?

    如果 WHERE 子句中的邻域不存在 如何让 mysql 数据库返回 0 因此 在下面的示例中 旧城区不在数据库中 我希望数据库返回 0 个事件而不是空结果 SELECT incidents neighborhoods FROM myTab
  • 如何解决postgresql中group by和聚合函数的问题

    我正在尝试编写一个查询来划分两个 SQL 语句 但它显示了我 ERROR column temp missed must appear in the GROUP BY clause or be used in an aggregate fu

随机推荐

  • 常用通信时序之UART、IIC、SPI(基于STM32)

    常用通信时序 xff08 UART IIC SPI xff0c RS232 RS485 xff09 及协议 xff08 Modbus xff09 通讯时序1 UART2 IIC3 SPI4 RS3235 RS485 通信协议1 Modbus
  • 如何使用SVN查看具体某行代码的提交人、合并分支或者拉取新分支

    1 如何在SVN上查看具体某一行代码的提交人 xff1a 首先选中该文件 xff0c 然后点击 追溯 xff0c 如上图可以选择该文件对应的版本区间 默认不需要设置 如果需要查询该文件在某个特定版本区间的修改人 xff0c 则可以在上面设定
  • 针对lenovo R7000平台的Ubuntu 18.04双硬盘双系统搭建

    双固态双系统安装 分区及启动挂载点 双固态需要把EFI启动项放在同一个硬盘中即在ubuntu分区时应将efi分区建立在和win10同一硬盘中 xff0c 选择启动挂载点时选择该efi分区或者直接不建立efi分区 xff0c 直接挂载在win
  • 如何使用ublox ZED-F9P 配置基准站、移动站+差分电台实现RTK定位

    格林恩德F9P RTK模块 xff0c 集成高精度板卡 ZED F9P 可同时接收GPS 北斗 xff0c GALILEO GLONASS 卫星系统的L1 L2频点 xff0c 结合高精度天线一体化设计 xff0c 体积小 xff0c 重量
  • 北斗卫星导航有哪些频段

    北斗系统是全球第一个提供三频信号服务的卫星导航系统 xff0c GPS使用的是双频信号 xff0c 这是北斗的后发优势 使用双频信号可以减弱电离层延迟的影响 xff0c 而使用三频信号可以构建更复杂模型消除电离层延迟的高阶误差 同时 xff
  • 北斗短报文介绍

    1 什么是北斗短报文通信 xff1f 北斗系统的短报文通信 xff0c 是指北斗地面终端和北斗卫星 北斗地面监控总站之间能够直接通过卫星信号进行双向的信息传递 xff0c 通信以短报文 xff08 类似手机短信 xff09 为传输基本单位
  • 什么是星基增强系统SBAS

    SBAS xff1a 英文全称Satellite Based Augmentation System xff0c 中文意思是广域差分增强系统 xff0c 如果不知道这是什么意思 xff0c 那么说星基增强系统相信大家都知道 广域差分增强系统
  • GNSS PPP和PPK区别

    01 PPP PPP全称Precise Point Positioning xff0c 译为精密单点定位 xff0c 属于单点定位也叫绝对定位 xff0c 精密单点定位是指利用载波相位观测值以及由IGS等组织提供的高精度的卫星星历及卫星钟差
  • 三轴加速度计计算俯仰角、横滚角、偏航角

    pitch是俯仰角 xff0c 是 点头 xff0c xff08 在固定翼飞机中则由升降舵舵机控制 xff09 yaw是偏航角 xff0c 是 摇头 xff0c xff08 在固定翼飞机中则由方向舵舵机控制 xff09 roll是旋转角 x
  • 如何使用UBLOX ZED-F9P +4G获取千寻差分,实现厘米级定位同时回传到IP服务器

    格林恩德F9P 4G RTK模块 xff0c 集成高精度板卡ZED F9P以及4G模组 xff0c 可同时接收GPS xff0c 北斗 xff0c GALILEO GLONASS卫星系统的L1 L2频点 xff0c 结合高精度天线一体化设计
  • 小型RTK/LITE RTK/Mini RTK CR202(9P+4G+imu) 惯导 实现高精度厘米级定位,输出组合导航位置,定位数据回传服务器

    格林恩德 CR202 是一款小巧 迷你的RTK设备 xff0c 集成高精度板卡 ZED F9P 与4G EC20通信模组 xff0c 内置惯性导航IMU三轴加速度计 三轴陀螺仪 CAN收发器 xff0c 支持多种差分链路包括4G 电台 支持
  • 常用CORS账号设置方法(千寻CORS、中国移动CORS、六分CORS、北斗CORS、迅腾CORS)

    1 千寻CORS账号设置方法 2 中国移动CORS账号设置方法 3 六分CORS账号设置方法 4 北斗CORS账号设置方法 5 讯腾CORS账号设置方法 格林恩德专注GPS北斗高精度定位 北斗短报文通信与无线传输应用产品的开发与市场拓展
  • NTRIPClient_1.7 工具使用方法分享

    1 打开NTRIPClient 1 7软件 2 选择串口和波特率 xff0c 正确的与板卡或者模块连接 点击编辑 xff0c 进入串口配置界面 选择正确的端口和波特率 3 输入正确的差分账号 输入千寻差分账号地址 端口 用户名 账号密码 4
  • 导航卫星的时间系统

    1 GPS时间系统 xff08 GPST xff09 GPS系统是测时测距系统 时间在 GPS测量中是一个基本的观测量 卫星的信号 xff0c 卫星的运动 xff0c 卫星的坐标都与时间密切相关 对时间的要求既要稳定又要连续 为此 xff0
  • JT808协议介绍 --- 格林恩德 CR202 RTK 高精度车载定位器协议解读

    部标808又称为JT808 xff0c JT808标准的全称是 道路运输车辆卫星定位系统终端通讯协议及数据格式 808协议适用于GPS定位车载终端和监控平台之间的通信 当前市面上 xff0c 普通车辆监测设备所安装的GPS定位器 xff0c
  • C++析构函数调用顺序

    文章目录 析构函数工作过程 1 执行析构函数的函数体 2 如果该类中拥有类对象成员 xff0c 且类对象有析构函数 xff0c 则以类对象成员声明次序的相反顺序调用其析构函数 xff0c 销毁类对象成员 3 按原来构造顺序的相反顶序向上依次
  • TCP通信C++实现小例子

    TCP通信C 43 43 实现案例 https www bilibili com video BV1Dt411p74c t 61 1746 61 61 全部来自以上视频 xff0c 纯属搬运 xff0c 小可爱有问题可以举手提问哈 61 6
  • 串行通信简介

    一 串行通信与并行通信 计算机与外界的数据交换称为通信 xff0c 通信分为并行通信和串行通信两种基本方式 并行通信 串行通信 并行通信 xff1a 并行通信指各个数据位同时进行传送的数据通信方式 xff0c 因此有多少个数据位 xff0c
  • 使用寄存器点亮一个LED灯 普中科技stm32(stm32f1103zeb6)

    板子 xff1a 普中科技stm32F1 芯片stm32f1103zet6 1 程序如下 xff1a include 34 stm32f10x h 34 导入头文件 typedef unsigned int u32 typedef是系统关键
  • day 5 select服务器和客户端

    select客户端代码 xff1a include lt stdio h gt include lt string h gt include lt sys socket h gt include lt netinet in h gt inc