Linux下select异步通讯怎么实现

62次阅读
没有评论

共计 5819 个字符,预计需要花费 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 行业资讯频道。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-12发表,共计5819字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)