共计 5794 个字符,预计需要花费 15 分钟才能阅读完成。
这篇文章主要介绍“Linux 下 select 异步通讯如何实现”的相关知识,丸趣 TV 小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Linux 下 select 异步通讯如何实现”文章能帮助大家解决问题。
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(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(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!
关于“Linux 下 select 异步通讯如何实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注丸趣 TV 行业资讯频道,丸趣 TV 小编每天都会为大家更新不同的知识点。
正文完