Linux异步通信socket.docx
《Linux异步通信socket.docx》由会员分享,可在线阅读,更多相关《Linux异步通信socket.docx(19页珍藏版)》请在冰豆网上搜索。
Linux异步通信socket
什么是异步通讯?
就是通讯任意一方可以任意发送消息,有消息来到时会收到系统提示去接收消息。
这里要用到select函数。
使用步骤如下:
1、设置一个集合变量,用来存放所有要判断的句柄(filedescriptors:
即我们建立的每个socket、用open打开的每个文件等)
2、把需要判断的句柄加入到集合里
3、设置判断时间
4、开始等待,即select
5、如果在设定的时间内有任何句柄状态变化了就马上返回,并把句柄设置到集合里
服务器端源代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineMAXBUF1024
/************关于本文档********************************************
*filename:
async-server.c
*purpose:
演示网络异步通讯,这是服务器端程序
*wroteby:
zhoulifa(zhoulifa@)周立发()
Linux爱好者Linux知识传播者SOHO族开发者最擅长C语言
*datetime:
2007-01-2521:
22
*Note:
任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
*但请遵循GPL
*Thanksto:
G
*Hope:
希望越来越多的人贡献自己的力量,为科学技术发展出力
*科技站在巨人的肩膀上进步更快!
感谢有开源前辈的贡献!
*********************************************************************/
intmain(intargc,char**argv)
{
intsockfd,new_fd;
socklen_tlen;
structsockaddr_inmy_addr,their_addr;
unsignedintmyport,lisnum;
charbuf[MAXBUF+1];
fd_setrfds;
structtimevaltv;
intretval,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=inet_addr(argv[3]);
else
my_addr.sin_addr.s_addr=INADDR_ANY;
if(bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr))
==-1){
perror("bind");
exit
(1);
}
if(listen(sockfd,lisnum)==-1){
perror("listen");
exit
(1);
}
while
(1){
printf
("\n----等待新的连接到来开始新一轮聊天……\n");
len=sizeof(structsockaddr);
if((new_fd=
accept(sockfd,(structsockaddr*)&their_addr,
&len))==-1){
perror("accept");
exit(errno);
}else
printf("server:
gotconnectionfrom%s,port%d,socket%d\n",
inet_ntoa(their_addr.sin_addr),
ntohs(their_addr.sin_port),new_fd);
/*开始处理每个新连接上的数据收发*/
printf
("\n准备就绪,可以开始聊天了……直接输入消息回车即可发信息给对方\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出错!
%s",strerror(errno));
break;
}elseif(retval==0){
/*printf
("没有任何消息到来,用户也没有按键,继续等待……\n");*/
continue;
}else{
if(FD_ISSET(0,&rfds)){
/*用户按键了,则读取用户输入的内容发送出去*/
bzero(buf,MAXBUF+1);
fgets(buf,MAXBUF,stdin);
if(!
strncasecmp(buf,"quit",4)){
printf("自己请求终止聊天!
\n");
break;
}
len=send(new_fd,buf,strlen(buf)-1,0);
if(len>0)
printf
("消息:
%s\t发送成功,共发送了%d个字节!
\n",
buf,len);
else{
printf
("消息'%s'发送失败!
错误代码是%d,错误信息是'%s'\n",
buf,errno,strerror(errno));
break;
}
}
if(FD_ISSET(new_fd,&rfds)){
/*当前连接的socket上有消息到来则接收对方发过来的消息并显示*/
bzero(buf,MAXBUF+1);
/*接收客户端的消息*/
len=recv(new_fd,buf,MAXBUF,0);
if(len>0)
printf
("接收消息成功:
'%s',共%d个字节的数据\n",
buf,len);
else{
if(len<0)
printf
("消息接收失败!
错误代码是%d,错误信息是'%s'\n",
errno,strerror(errno));
else
printf("对方退出了,聊天终止\n");
break;
}
}
}
}
close(new_fd);
/*处理每个新连接上的数据收发结束*/
printf("还要和其它连接聊天吗?
(no->退出)");
fflush(stdout);
bzero(buf,MAXBUF+1);
fgets(buf,MAXBUF,stdin);
if(!
strncasecmp(buf,"no",2)){
printf("终止聊天!
\n");
break;
}
}
close(sockfd);
return0;
}
客户端源代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineMAXBUF1024
/************关于本文档********************************************
//*filename:
ssync-client.c
*purpose:
演示网络异步通讯,这是客户端程序
*wroteby:
zhoulifa(zhoulifa@)周立发()
Linux爱好者Linux知识传播者SOHO族开发者最擅长C语言
*datetime:
2007-01-2521:
32
*Note:
任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
*但请遵循GPL
*Thanksto:
G
*Hope:
希望越来越多的人贡献自己的力量,为科学技术发展出力
*科技站在巨人的肩膀上进步更快!
感谢有开源前辈的贡献!
*********************************************************************/
intmain(intargc,char**argv)
{
intsockfd,len;
structsockaddr_indest;
charbuffer[MAXBUF+1];
fd_setrfds;
structtimevaltv;
intretval,maxfd=-1;
if(argc!
=3){
printf
("参数格式错误!
正确用法如下:
\n\t\t%sIP地址端口\n\t比如:
\t%s127.0.0.180\n此程序用来从某个IP地址的服务器某个端口接收最多MAXBUF个字节的消息",
argv[0],argv[0]);
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],(structin_addr*)&dest.sin_addr.s_addr)==0){
perror(argv[1]);
exit(errno);
}
/*连接服务器*/
if(connect(sockfd,(structsockaddr*)&dest,sizeof(dest))!
=0){
perror("Connect");
exit(errno);
}
printf
("\n准备就绪,可以开始聊天了……直接输入消息回车即可发信息给对方\n");
while
(1){
/*把集合清空*/
FD_ZERO(&rfds);
/*把标准输入句柄0加入到集合中*/
FD_SET(0,&rfds);
maxfd=0;
/*把当前连接句柄sockfd加入到集合中*/
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出错!
%s",strerror(errno));
break;
}elseif(retval==0){
/*printf
("没有任何消息到来,用户也没有按键,继续等待……\n");*/
continue;
}else{
if(FD_ISSET(sockfd,&rfds)){
/*连接的socket上有消息到来则接收对方发过来的消息并显示*/
bzero(buffer,MAXBUF+1);
/*接收对方发过来的消息,最多接收MAXBUF个字节*/
len=recv(sockfd,buffer,MAXBUF,0);
if(len>0)
printf
("接收消息成功:
'%s',共%d个字节的数据\n",
buffer,len);
else{
if(len<0)
printf
("消息接收失败!
错误代码是%d,错误信息是'%s'\n",
errno,strerror(errno));
else
printf("对方退出了,聊天终止!
\n");
break;
}
}
if(FD_ISSET(0,&rfds)){
/*用户按键了,则读取用户输入的内容发送出去*/
bzero(buffer,MAXBUF+1);
fgets(buffer,MAXBUF,stdin);
if(!
strncasecmp(buffer,"quit",4)){
printf("自己请求终止聊天!
\n");
break;
}
/*发消息给服务器*/
len=send(sockfd,buffer,strlen(buffer)-1,0);
if(len<0){
printf
("消息'%s'发送失败!
错误代码是%d,错误信息是'%s'\n",
buffer,errno,strerror(errno));
break;
}else
printf
("消息:
%s\t发送成功,共发送了%d个字节!
\n",
buffer,len);
}
}
}
/*关闭连接*/
close(sockfd);
return0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineMAXBUF1024
/************关于本文档********************************************
//*filename:
ssync-client.c
*purpose:
演示网络异步通讯,这是客户端程序
*wroteby:
zhoulifa(zhoulifa@)周立发()
Linux爱好者Linux知识传播者SOHO族开发者最擅长C语言
*datetime:
2007-01-25