多路I/O复用之select函数

关于select函数的各个参数以及多路I/O复用,上面的这篇博客介绍的很清楚了.走一遍实现代码
这个代码主要是实现udp同时能够进行收发

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
int main(int argc,char *argv[])
{
	int udpfd = 0;
	struct sockaddr_in saddr;
	struct sockaddr_in caddr;
//初始化结构体地址 
	bzero(&saddr,sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port   = htons(8000);
	saddr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	bzero(&caddr,sizeof(caddr));
	caddr.sin_family  = AF_INET;
	caddr.sin_port    = htons(8000);
	
	//创建套接字
	if( (udpfd = socket(AF_INET,SOCK_DGRAM, 0)) < 0)
	{
		perror("socket error");
		exit(-1);
	}
	
	//套接字端口绑字
	if(bind(udpfd, (struct sockaddr*)&saddr, sizeof(saddr)) != 0)
	{
		perror("bind error");
		close(udpfd);		
		exit(-1);
	}
 
	printf("input: \"sayto 192.168.220.X\" to sendmsg to somebody\033[32m\n");	
	while(1)
	{	
/*

typedef struct
{
#ifdef__USE_XOPEN
__fd_maskfds_bits[__FD_SETSIZE/__NFDBITS];
#define__FDS_BITS(set)((set)->fds_bits)
#else
__fd_mask__fds_bits[__FD_SETSIZE/__NFDBITS];
#define__FDS_BITS(set)((set)->__fds_bits)
#endif
}fd_set
select()机制中提供一fd_set的数据结构,实际上是一long类型的数组,

*/
		char buf[100]="";	
		fd_set rset;	//创建文件描述符的聚合变量	
		FD_ZERO(&rset); //文件描述符聚合变量清0
		FD_SET(0, &rset);//将标准输入添加到文件描述符聚合变量中
		FD_SET(udpfd, &rset);//将udpfd添加到文件描述符聚合变量中		
		write(1,"UdpQQ:",6);//向标准输出中写入:UdpQQ字样
		
		if(select(udpfd + 1, &rset, NULL, NULL, NULL) > 0)//select第一个参数是最大文件文描述符的数量+1
		{
			if(FD_ISSET(0, &rset))//测试0是否可读写
			{				
				fgets(buf, sizeof(buf), stdin);//从键盘输入字符存入缓冲区
				buf[strlen(buf) - 1] = '\0';//缓冲字符串末尾加入'\0'
				if(strncmp(buf, "sayto", 5) == 0)//比较buf中有没有sayto 字样
				{
					char ipbuf[16] = "";
					inet_pton(AF_INET, buf+6, &caddr.sin_addr);//给addr套接字地址再赋值. 如果buff后面接地址了 那么将那个地址转换
					printf("\rsay to %s\n",inet_ntop(AF_INET,&caddr.sin_addr,ipbuf,sizeof(ipbuf)));
					continue;
				}
				else if(strcmp(buf, "exit")==0)//如果出现exit  则退出
				{
					close(udpfd);
					exit(0);
				}
				sendto(udpfd, buf, strlen(buf),0,(struct sockaddr*)&caddr, sizeof(caddr));//发送出去
			}
			if(FD_ISSET(udpfd, &rset))//测试udpfd是否可读写
			{
				struct sockaddr_in addr;
				char ipbuf[INET_ADDRSTRLEN] = "";
				socklen_t addrlen = sizeof(addr);
				
				bzero(&addr,sizeof(addr));
				//显示收到信息
				recvfrom(udpfd, buf, 100, 0, (struct sockaddr*)&addr, &addrlen);
				printf("\r\033[31m[%s]:\033[32m%s\n",inet_ntop(AF_INET,&addr.sin_addr,ipbuf,sizeof(ipbuf)),buf);
			}
		}
	}
	
	return 0;
}
 


测试过程有点绕 首先我们执行可执行文件 我们可以发现

input: "sayto 192.168.220.X" to sendmsg to somebody
UdpQQ:nihao
[127.0.0.1]:nihao

写出去写信息 然后本机提示收到了
下面在键盘中输入

UdpQQ:sayto 202.199.xxx.xxx  //你的电脑的ip地址
UdpQQ:zaijian//在输入你想说的话
[202.199.xxx.xxx]:zaijian//就会直接在屏幕上显示收到了什么信息


至此就可以完成同时收发.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值