linux网络编程:select 的的问题
下面是 echo 服务器和客户端的程序,其中服务器端使用了 select 来监听套接字是否可读,在客户端只是使用简单的阻塞I/O,但是发现一个诡异的执行结果。
//服务器
#include "../unpv13e/lib/unp.h"
int main(int argc, char** argv)
{
int i,maxi,maxfd,listenfd,connfd,sockfd;
int nready,client[FD_SETSIZE];
ssize_t n;
fd_set rset,allset;
char buf[MAXLINE];
socklen_t clilen;
struct sockaddr_in cliaddr,servaddr;
listenfd = Socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8080);
Bind(listenfd,(SA *) &servaddr,sizeof(servaddr));
Listen(listenfd,LISTENQ);
maxfd = listenfd;
maxi = -1;
for(i=0; i<FD_SETSIZE; i++)
client[i] = -1;
FD_ZERO(&allset);
FD_SET(listenfd,&allset);
for( ; ; )
{
rset = allset;
nready = Select(maxfd+1,&rset,NULL,NULL,NULL);//select listenfd
//printf("ready to read:%d\n",nready);
if(FD_ISSET(listenfd,&rset))
{
clilen = sizeof(cliaddr);
connfd = Accept(listenfd,(SA *)&cliaddr,&clilen);
for(i=0; i<FD_SETSIZE; i++)//put connfd into client array
{
if(client[i] < 0)
{
client[i] = connfd;
break;
}//if
}//for
if(i == FD_SETSIZE)
err_quit("too many clients");
FD_SET(connfd,&allset);
if(connfd > maxfd)
maxfd = connfd;
if(i > maxi)
i = maxi;
if(--nready <= 0)//maybe there is only listenfd that is ready to read
continue;
}//if
printf("reading:%d\n",maxi);
for(i=0; i<=maxi; i++)
{
if( (sockfd = client[i]) < 0)
continue;
if(FD_SET(sockfd,&rset))
{
if( (n=Read(sockfd,buf,MAXLINE)) == 0)//FIN
{
Close(sockfd);
FD_CLR(sockfd,&allset);
client[i] = -1;
}
else if(n < 0)//socket error
err_quit("socket error");
else
Writen(sockfd,buf,n);
if(--nready <= 0)break;
}//if
}//for
}//for
return 0;
}
//客户端
#include "../unpv13e/lib/unp.h"
void str_cli(FILE *fp,int sockfd)
{
char sendline[MAXLINE],recvline[MAXLINE];
while(Fgets(sendline,MAXLINE,fp) != NULL)
{
Writen(sockfd,sendline,strlen(sendline));
if(Readline(sockfd,recvline,MAXLINE) == 0)
err_quit("str_cli:server terminated prematurely");
Fputs(recvline,stdout);
}//while
}
int main(int argc,char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage:tcpcli <IPaddress>");
sockfd = Socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8080);
Inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
Connect(sockfd,(SA *)&servaddr,sizeof(servaddr));
str_cli(stdin,sockfd);
exit(0);
}
测试的时候,先启动服务器,接着启动客户端,然后在客户端输入字符串,但是服务器的输出结果:
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
reading:-1
........
而且在强制结束客户端的时候,依然没有阻止以上输出! Linux 网络编程 select 服务器
[解决办法]
你自己赋值的maxi = -1;你问谁呢。