Linux socket网络编程之聊天室(三):select异步通讯实现

2023-05-16

1.服务器端

/*select_server.c 2011.9.2 by yyg*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <unistd.h>

#define MAXBUF 1024

int main(int argc,char **argv){
	int sockfd,new_fd;
	socklen_t len;
	struct sockaddr_in my_addr,their_addr;
	unsigned int myport,lisnum;
	char buf[MAXBUF+1];
	fd_set rfds;
	struct timeval tv;
	int retval,maxfd = -1;

	if(argv[1]){
		myport = atoi(argv[1]);
	}
	else
		myport = 7838;

	if(argv[2]){
		lisnum = atoi(argv[2]);
	}
	else
		lisnum =2;
	if((sockfd = socket(PF_INET,SOCK_STREAM,0))== -1){
		perror("socket");
		exit(1);
	}

	bzero(&my_addr,sizeof(my_addr));
	my_addr.sin_family = PF_INET;
	my_addr.sin_port = htons(myport);
	if(argv[3])
		my_addr.sin_addr.s_addr = INADDR_ANY;
	
	if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == -1){
		perror("bind");
		exit(1);
	}
	
	if(listen(sockfd, lisnum) == -1){
		perror("listen");
		exit(1);
	}
	
	while(1){
		printf("\n----waiting for new connecting to start new char----\n");
		len = sizeof(struct sockaddr);
		if((new_fd = accept(sockfd,(struct sockaddr *)&their_addr,&len)) == -1){
			perror("accept");
			exit(errno);
		}
		else
			printf("server:got connection from %s,port %d,socked %d\n",\
				inet_ntoa(their_addr.sin_addr),\
				ntohs(their_addr.sin_port),new_fd);
		
		/*开始处理每个新连接上的数据收发*/
		//printf("\n---ready to go.now you can chatting...input enter,then you can chat---\n");
		while(1){
			/*把集合清空*/
			FD_ZERO(&rfds);
			/*把标准输入句柄0加入到集合中*/
			FD_SET(0,&rfds);
			maxfd = 0;
			/*把当前连接句柄new_fd加入到集合中*/
			FD_SET(new_fd,&rfds);
			if(new_fd > maxfd)
				maxfd = new_fd;
			/*设置最大等待时间*/
			tv.tv_sec = 1;
			tv.tv_usec = 0;

			retval = select(maxfd+1,&rfds,NULL,NULL,&tv);
			if(retval == -1){
				printf("select error!%s\n",strerror(errno));
				break;
			}
			else if(retval == 0){
				//printf("no message come,user no press the button,please wait...\n");
				continue;
			}
			else{

				if(FD_ISSET(new_fd,&rfds)){
				/*连接的socket 上有消息则接收并显示*/
					bzero(buf,MAXBUF+1);
					/*接收对方发过来的消息,最多MAXBUF字节*/
					len = recv(new_fd, buf, MAXBUF, 0);
					if(len > 0)
						printf("recv msg success:%s! %d bytes rcv.\n ",buf,len);
					else{
						if(len < 0){
							printf("recv msg fail.the errno is:%d,error info is %s.\n",errno,strerror(errno));
						}
						else
							printf("quit.\n");
						break;
					}
				}// FD_ISSET = sockfd情况
				if(FD_ISSET(0,&rfds)){
					/*用户有输入了,则读取其内容并发送*/
					bzero(buf, MAXBUF+1);
					fgets(buf, MAXBUF, stdin);
					if(!strncasecmp(buf, "quit", 4)){
						printf("self request to quit the chating\n");
						break;
					}
					/*发消息给服务器*/
					len = send(new_fd, buf, strlen(buf)-1 , 0);
					if(len < 0){
						printf("mgs:%s send fail!errno is:%d,error info is:%s\n", buf, errno, strerror(errno));
						break;
					}else{
						printf("msg: %s\t send success, send %d bytes!\n", buf, len);
					}
				}//FD_ISSET = 0
			
			}//select 处理结束
			
		}/*内while*/
		close(new_fd);
		/*处理每个新连接上的数据收发结束*/
		printf("would you want to chatting with another one?(no->quit)");
		fflush(stdout);
		bzero(buf,MAXBUF+1);
		fgets(buf,MAXBUF,stdin);
		if(!strncasecmp(buf,"no",2)){
			printf("quit the chatting!\n");
			break;
		}
	
	}/*外while*/

	close(sockfd);
	return 0;
}

2.客户端

/*select_client.c 2011.9.2 by yyg*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <resolv.h>

#define MAXBUF 1024
int main(int argc,char **argv){
	int sockfd,len;
	struct sockaddr_in dest;
	char buffer[MAXBUF+1];
	fd_set rfds;
	struct timeval tv;
	int retval,maxfd = -1;

	if(argc != 3){
		printf("the param style wrong!\n");
		exit(0);
	}
	/*创建一个socket用于tcp通信*/
	if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
		perror("socket");
		exit(errno);
	}

	/*初始化服务器端(对方)的地址和端口信息*/
	bzero(&dest,sizeof(dest));
	dest.sin_family = AF_INET;
	dest.sin_port = htons(atoi(argv[2]));
	if(inet_aton(argv[1],(struct in_addr *)&dest.sin_addr.s_addr) == 0){
		perror(argv[1]);
		exit(errno);
	}

	/*conect to the server*/
	if(connect(sockfd,(struct sockaddr*)&dest,sizeof(dest)) !=0){
		perror("connect");
		exit(errno);
	}

	printf("\n---ready to chatting...---\n");
	while(1){
		/*把集合清空*/
		FD_ZERO(&rfds);
		/*把标准输入句柄0加入到集合中*/
		FD_SET(0,&rfds);
		maxfd = 0;
		/*把当前连接句柄socket 加入到集合中*/
		FD_SET(sockfd,&rfds);
		if(sockfd > maxfd)
			maxfd = sockfd;
		/*设置最大等待时间*/
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		/*开始等待*/
		retval = select(maxfd+1,&rfds,NULL,NULL,&tv);
		if(retval == -1){
			printf("select error,quit!\n");
			break;
		}else if(retval == 0){
			continue;
		}else{
			if(FD_ISSET(sockfd,&rfds)){
				/*连接的socket 上有消息则接收并显示*/
				bzero(buffer,MAXBUF+1);
				/*接收对方发过来的消息,最多MAXBUF字节*/
				len = recv(sockfd, buffer, MAXBUF, 0);
				if(len > 0)
					printf("recv msg success:%s! %d bytes rcv.\n ",buffer,len);
				else{
					if(len < 0){
						printf("recv msg fail.the errno is:%d,error info is %s.\n",errno,strerror(errno));
					}
					else
						printf("quit.\n");
					break;
				}
			}// FD_ISSET = sockfd情况
			if(FD_ISSET(0,&rfds)){
				/*用户有输入了,则读取其内容并发送*/
				bzero(buffer, MAXBUF+1);
				fgets(buffer, MAXBUF, stdin);
				if(!strncasecmp(buffer, "quit", 4)){
					printf("self request to quit the chating\n");
					break;
				}
				/*发消息给服务器*/
				len = send(sockfd, buffer, strlen(buffer)-1 , 0);
				if(len < 0){
					printf("mgs:%s send fail!errno is:%d,error info is:%s\n", buffer, errno, strerror(errno));
					break;
				}else{
					printf("msg: %s\t send success, send %d bytes!\n", buffer, len);
				}
			}//FD_ISSET = 0
			
		}//select 处理结束

	}//处理聊天的while 循环
	/*关闭连接*/
	close(sockfd);
	return 0;
}

运行结果:

终端1:服务器端

[root@localhost net]# ./select_server 7838

----waiting for new connecting to start new char----
server:got connection from 172.31.100.236,port 59462,socked 4
recv msg success:kfldsjfk! 8 bytes rcv.
456354
 msg: 456354
         send success, send 6 bytes!
recv msg success:453455! 6 bytes rcv.

终端2:客户端

[root@localhost net]#  ./select_client 172.31.100.236 7838

---ready to chatting...---
kfldsjfk
msg: kfldsjfk
         send success, send 8 bytes!
recv msg success:456354! 6 bytes rcv.
453455
 msg: 453455
         send success, send 6 bytes!





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

Linux socket网络编程之聊天室(三):select异步通讯实现 的相关文章

  • 数据结构之队列

    一 链式队列 数据结构 xff1a 两个指向节点的指针front rear 当链队为空时 xff0c front和rear都指向头节点 因此出队时 xff0c 删除队尾节点时要注意 xff01 link queue h 1 typedef
  • 二叉树

    1 二叉树节点的创建 xff08 初始化 xff09 tree c include lt stdlib h gt include 34 tree h 34 struct tree node tree node create data t d
  • 单机千万并发连接实战(修订版)

    c10k xff0c c100k xff0c c1000k等问题大家都已经司空见惯 xff0c 那么10m xff08 千万 xff09 并发连接呢 xff1f 今天就来一起挑战一下 下面我们使用handy库自带的例子程序 xff0c 来跑
  • 如何替换某文件中的所有的特定字符?---linux sed命令(文本编辑命令)

    sed是一个很好的文件处理工具 xff0c 主要是以行为单位进行处理 xff0c 可以将数据行进行替换 删除 新增 选取等特定工作 总 xff1a sed处理对象是文件 xff0c 怎么处理 xff1f 是以逐行处理 xff0c 何种处理
  • WEB点对点程序传输数据,是用HTTP协议还是TCP/IP协议?

    WEB点对点程序传输数据 xff0c 是用HTTP协议还是TCP IP协议 Tcp Ip协议和Http协议有什么区别 两个Web程序点对点传送数据 你会选择那一个 xff1f 今天在网上看到这样一个面试题目 xff0c 引发了一连串的查找资
  • 斜杠“/” 反斜杠“\”

    在Unix Linux中 xff0c 路径的分隔采用正斜杠 34 34 xff0c 比如 34 home hutaow 34 xff1b 而在Windows中 xff0c 路径分隔采用反斜杠 34 34 xff0c 比如 34 C Wind
  • C++ sort()函数cmp的含义

    头文件 xff1a include lt algorithm gt std sort first last cmp 使用的范围是 first last 省略 cmp xff0c 使用 sort first last 则默认从 小到大排序 使
  • win10应用商店安装Ubuntu全攻略及问题解决

    纳德拉说Windows love Linux xff0c 所以win10的Microsoft Store就支持了像安装软件一样安装Linux系统 操作如下 xff1a Microsoft Store搜索Linux 可以搜索到多个Linux发
  • 因子和的计算方法

    因子和的计算方法 神马叫因子和 xff1a 一个数的所以因子的和就叫因子和 好吧 xff0c 举个例子 xff1a 12的因子和为 xff1a 1 43 2 43 3 43 4 43 6 43 12 计算方法是把12分解为质因数的表达形式2
  • Windows 10 技术预览版:通过组策略来更改Windows 更新自动检查下载和安装设置

    xfeff xfeff 在Windows 10 技术预览版中 xff0c Windows 更新中是默认设置为自动检查更新并下载安装 xff0c 选项无法更改 xff0c 这里主要是微软做了设置 但我们可以通过组策略来更改这一设置 xff0c
  • 综合处理 'conda' 不是内部或外部命令,也不是可运行的程序 或批处理文件。

    问题描述 xff1a cmd中输入python正确 xff0c 输入conda错误 电脑之前有python3 7的配置环境 xff0c 一直用IDLE编程 xff0c 后面安装Anaconda时 xff0c 默认安装并没有手动添加path
  • 【无标题】tp4056充电原理图

    一 以上原理图 xff0c 充包之前不会转灯 xff0c 记得用DC source 充了好久都没有转绿灯状态
  • 2.玩客云armbian5.9安装docker

    1 换源 命令 xff1a nano etc apt sources list 用以下内容替换原文件内容 deb https mirrors ustc edu cn debian buster main contrib non free d
  • JAVA架构之路(数据加密与常见加密算法)

    常见加密算法以及安全级别和使用场景 DES xff08 安全级别不高 xff0c 消耗性能 较小 xff09 AES xff08 安全级别较高 xff09 MD5 xff08 安全级别较高 xff0c 一般不用做加密 xff0c 常用在校验
  • 这些Python计算机视觉工具,帮你coding事半功倍

    作为开发人员喜爱的语言之一 xff0c Python以其丰富的社区可用工具和库而闻名 我们列出了开发人员可以用于计算机视觉10个流行流行的Python库或平台 xff0c 以帮助开发人员自动化开发任务 xff0c 其中包括检测和可视化 1
  • iis7.5 的解析漏洞(iis7.5 解析漏洞解决方案)

    一 iis7 5 的解析漏洞介绍 漏洞影响 IIS7 及IIS7 5 在使FastCGI方式调用php时 在php ini里设置 cgi fix pathinfo 1 使得访问任意文件URL时 在URL后面添加 x php 等字符时 该文件
  • 百度推广优化(百度推广优化技巧)

    百度推广优化是一种提高网站在百度搜索引擎中曝光率的有效方法 通过对网站进行优化 可以使其在百度搜索结果页面中排名更靠前 从而增加网站的点击量和流量 百度推广优化就是花钱获得在百度上竞争广告位 增加曝光率和变现的可能性 而在做百度推广优化应该
  • 百度推广优化(百度推广优化方法)

    百度推广优化是什么意思 百度推广优化是指通过花钱获得在百度上竞争广告位 推广优化的位置越靠前 越能得到曝光 越能增加被变现的可能性 大家都想在搜索引擎中获得主页的顶级排名 那么我们必须根据一些优化的营销推广策略和技提高网站在搜索引擎中的排名
  • 程序猿健康养生口诀和食谱来了

    程序猿健康养生口诀和食谱来了1 饱不洗头 饿不洗澡 冷水洗脸 美容保健 汗水没落 冷水莫浇 温水刷牙 防敏固齿 2 吃米带糠 吃菜带帮 男不离韭 女不离藕 青红萝卜 生克熟补 食不过饱 饱不急卧 3 养生在动 养心在静 心不清净 思虑妄生
  • 数据可视化数据存储

    数据可视化数据存储是根据不同的需求 要爬取的数据可能会很多 这时就需要把数据保存下来进行后续的清理 分析和统计操作 常用的存储方式有数据库存储和文件存储等 其中 使用数据库方式来存储数据涉及不同的数据库系统 每种数据库系统之间的差别也很大

随机推荐

  • 数据可视化数据存储的好处

    数据可视化定义 xff1a 通过可视表达增强人们完成某些任务的效率 数据可视化数据存储是现代商业活动中经常会使用到的一种方法 xff0c 相对于其他的方式来讲它可以使数据的变化变得更为直观 xff0c 而大量的数据可视化之后会有很多人选择将
  • 泛微移动平台e-mobile漏洞利用

    泛微移动平台e mobile漏洞利用基本信息 漏洞情报编号 xff1a vulbox intel 15244 是否可自动化组件 xff1a 是 CVE ID xff1a 暂无 发布日期 xff1a 2022 04 01 15 48 45 C
  • 泛微移动平台e-mobile漏洞利用的修复方案

    泛微移动平台e mobile漏洞利用的修复方案 1 对产生漏洞模块的传入参数进行有效性检测 xff0c 对传入的参数进行限定 2 当用户输入限定字符时 xff0c 立刻转向自定义的错误页 xff0c 不能使用服务器默认的错误输出方式 3 对
  • /.well-known/ 漏洞

    well known openid configuration 这些通常会返回一个 JSON 配置文件 其中包含关键信息 站点中隐藏的 well known 目录是IETF定义的知名站点的URI前缀 常被用来证明域名的所有权 使用ACME来
  • 电脑编程自学(零基础自学编程怎么入门)

    电脑编程自学入手 确定编程学习的方向 编程语言有多种 php C C C JAVA Python等 每种语言都有不同的优缺点 可以根据自己的兴趣方向选择一门编程语言作为自己的学习目标 基础阶段的语法学习 学习任何一门编程语言 都需要掌握其编
  • Linux(Linux各目录结构详解)

    我们知道Linux系统是一个文件系统 xff0c 它的文件系统就类似windows系统下的磁盘文件系统 我们连接上一台linux系统的服务器 输入命令 xff1a ls 我们可以看到 linux系统的根目录下有这些目录 bin boot d
  • 电脑编程自学(电脑编程自学能学会吗)

    电脑编程自学能学会吗 自己学习编程是能学会的 如果你愿意每天为学习编码付出一点努力 那么通过免费的在线资源以及利用Quora等平台提供的其他支持渠道 你绝对有可能做到这一点 所以不要犹豫 迈出学习如何编写代码的第一步 并看着自己随着时间的推
  • bbwbbw(Java打印输出bbwbbw)

    Java打印输出数据println和print打印输出数据 xff0c System out println 34 bbwbbw 34 System out println 34 h5 bbwbbw 34 h5 bbwbbw System
  • 需要家长或监护人同意才能使用该账户

    使用微软账户登录时提示 需要家长或监护人同意才能使用该账户 的处理方法 xff0c 电脑登录提示这个 需要家长或监护人同意才能使用该账户 1 点击了解更多关于家长监护人许可 xff0c 点击更新账户信息 xff0c 更改出生日期 xff0c
  • 电脑登录提示“需要家长或监护人同意才能使用该账户”

    今天装电脑 xff0c 电脑登录提示这个 需要家长或监护人同意才能使用该账户 使用微软账户登录时提示 需要家长或监护人同意才能使用该账户 的处理方法 xff1a 1 点击了解更多关于家长监护人许可 xff0c 点击更新账户信息 xff0c
  • 大b和小b的区别是什么

    计算机里大b和小b的区别是什么 B与b nbsp kbps字节宽带换算区别掉线 nbsp BYTE字节bit比特1B 8b这里指的是 带宽网速的 单位计算方 式方法及关 系 在计算机科学中 bit 比特 是表示信息的最小单位 叫做二进制位
  • https tk6 us

    https tk6 us专题 为您展现优质的https tk6 us各类信息 在这里您可以找到关于https tk6 us的相关内容及最新的https tk6 us贴子 https tk6 us服务器iP xff1a 当前解析 xff1a
  • cron表达式(cron表达式解析)

    Cron表达式是一个字符串 字符串以5或6个空格隔开 分为6或7个域 每一个域代表一个含义 Cron有如下两种语法格式 1 Seconds Minutes Hours DayofMonth Month DayofWeek Year 2 Se
  • sa账号密码在那个表里面

    sa账号密码在那个表里面 xff0c syslogins in master db 不过是加密的 xff0c 看不出是什么的 SA管理帐户是放在视图下的 master数据库 视图 sys sql logins sqlserver怎么查看sa
  • 《web开发: (Node.js)Express 接口、跨域CORS》

    一 Express 接口编写 1 创建基本的服务器 2 创建 API 路由模块 3 编写 GET 接口
  • Linux系统打包QT程序

    当前测试环境是 Ubuntu18 04 桌面版本 1 安装工具 sudo apt get install git g 43 43 libgl1 mesa dev当然你的Ubuntu肯定安装了QT工具 xff0c 通过QCreator等工具编
  • Linux(强大的yum命令)

    yum 读 j m xff0c 中文谐音 xff1a 样安ing yum xff08 Yellow dog Updater Modified xff09 是一个在 Fedora 和 RedHat 以及 SUSE 中的 Shell 前端软件包
  • Ubuntu 16.04 查看软件包的命令技巧

    Ubuntu作为一款常用的Linux系统 xff0c 有着Linux下常用的使用命令行操作模式 下面为大家介绍一些管理软件包的常用命令 下面的命令需要在终端下输入 xff0c 任何实用 sudo 作为前缀的命令都需要拥有root访问权限 x
  • 51单片机60秒倒计时 数码管显示

    51单片机60秒倒计时 数码管显示 本资源适用于初学者 xff0c 使用单片机型号为普中51单片机 xff1a 下面展示 代码 include 34 reg52 h 34 sbit LSA 61 P2 2 sbit LSB 61 P2 3
  • Linux socket网络编程之聊天室(三):select异步通讯实现

    1 服务器端 select server c 2011 9 2 by yyg include lt stdio h gt include lt stdlib h gt include lt errno h gt include lt str