I/O 多路选择示例 (select)

书中自有言如玉呀,select函数的使用方法,我在中间加入了一些printf语言,更方便理解程序的流程
客户端用之前的TCP例子就行了,见http://www.kumouse.com/article.asp?id=141

[ssj@main test]$ cat selectserver.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>

#define MAX 80

int port=65533;

void my_turn(char *p)
{sleep(5);
if (p == NULL)return;
while( *p != '')
{
if( *p >= (char)0x61 && *p <= (char)0x7a)
*p=(char)((int)*p-(int)0x20);
p++;
}
}

int main(void)
{
struct sockaddr_in sin,cin;
int lfd,cfd,sfd,rdy,client[FD_SETSIZE],maxi,maxfd;
fd_set rset,allset;
socklen_t addr_len;
char buf[MAX],str[INET_ADDRSTRLEN];
int i,n,len,opt=1;

bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_port=htons(port);

lfd=socket(AF_INET,SOCK_STREAM,0);
if(lfd==-1)
{perror("Fail to socket");exit(1); }

setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

if((n=bind(lfd,(struct sockaddr *)&sin,sizeof(sin)))==-1)
{perror("Fail to bind");exit(1);}

if((n=listen(lfd,20))==-1)
{perror("Fail to listen");exit(1);}

printf("running….n");

maxfd=lfd;
maxi=-1;

for(i=0;i<FD_SETSIZE;i++)
{client[i]=-1;}

FD_ZERO(&allset);
FD_SET(lfd,&allset);

while(1){
rset=allset;
rdy=select(maxfd+1,&rset,NULL,NULL,NULL);
printf("%dn",rdy);
if(FD_ISSET(lfd,&rset)){
printf("p1n");
addr_len=sizeof(sin);
if((cfd=accept(lfd,(struct sockaddr *)&cin,&addr_len))==-1)
{perror("Fail to accept");exit(1);}

for(i=0;i<FD_SETSIZE;i++)
if(client[i]<0){client[i]=cfd;break;}

if(i==FD_SETSIZE){printf("too many clientsn");exit(1);}

FD_SET(cfd,&allset);

if(cfd>maxfd)
maxfd=cfd;
if(i>maxi)
maxi=i;
if(–rdy<=0)
continue;
}

for(i=0;i<=maxi;i++){
if((sfd=client[i])<0)continue;

if(FD_ISSET(sfd,&rset)){
if((n=read(sfd,buf,MAX))==0){
printf("the other side has been close.n");
fflush(stdout);
close(sfd);
FD_CLR(sfd,&allset);
client[i]=-1;
}
else{
inet_ntop(AF_INET,&cin.sin_addr,str,sizeof(str));
printf("client IP:%s:%dn",str,ntohs(cin.sin_port));
my_turn(buf);
if((n=write(sfd,buf,n))==-1)exit(1);
}
if(–rdy<=0)break;
}
}
}
close(lfd);
return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注