首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

关于unix网络编程select函数总是返回0的有关问题

2012-04-22 
关于unix网络编程select函数总是返回0的问题服务器端:int StartListen(sLsnPort)char *sLsnPort{struct s

关于unix网络编程select函数总是返回0的问题
服务器端:
int StartListen(sLsnPort)
char *sLsnPort;  
{
struct sockaddr_in ServiceAddr;
struct sockaddr_in ClientAddr;
int nLsnSock = 0;
int nAcceptSock = 0;
int nPid = 0;
int status = 0;
int nReady = 0;
unsigned int nAddrlen = 0;
char sRecvBuffer[500],sSendBuffer[500];
fd_set socks;
struct timeval recvtime;
  
  int n1 = 0,n2 = 0;
  
 
/*创建套接字*/
if((nLsnSock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Create socket error:%s\r\n",strerror(errno));
return -1;
}
bzero(&ServiceAddr,sizeof(ServiceAddr));
ServiceAddr.sin_family = AF_INET;
ServiceAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

ServiceAddr.sin_port = htons(atoi(sLsnPort)); /*输入的端口号*/
/*绑定套接字*/
if(bind(nLsnSock,(struct sockaddr *)&ServiceAddr,sizeof(ServiceAddr)) < 0)
{
printf("Bind socket error:%s\r\n",strerror(errno));
return -1;
}
/*监听套接字*/
  if(listen(nLsnSock,MAX_THREAD) != 0)
  {
  printf("Listen socket error:%s\r\n",strerror(errno));
  close(nLsnSock);
  return -1;
  }
  /*设置阻塞时间*/
recvtime.tv_sec = 15; /*阻塞时间为15秒*/
recvtime.tv_usec = 0;

/*循环监听F5请求*/
while(1)
{
n1++;
n2++;
printf("n1 = %d\r\n",n1);
memset(sRecvBuffer,0,500);
memset(sSendBuffer,0,500);  
/* 检查是否有僵死进程 */
while(1)
{
nPid = wait3(&status, WNOHANG|WUNTRACED, NULL);
if(nPid > 0) 
{
kill(SIGTERM, nPid);
}
else
{
break;
}
}
FD_ZERO(&socks); /*清空套接字描述符集*/
FD_SET(nLsnSock,&socks); /*在文件描述符集socks中增加一个新的文件描述符nLsnSock*/

nReady = select(nLsnSock+1,&socks,NULL,NULL,&recvtime); /*阻塞*/
if(nReady <=0 )
{
printf("select socket error:%d\r\n",nReady);
continue;
}
printf("n2 = %d\r\n",n2);
if(FD_ISSET(nLsnSock,&socks))
{
nAddrlen =sizeof(ClientAddr);
nAcceptSock = accept(nLsnSock,(struct sockaddr *)&ClientAddr,&nAddrlen);
if(nAcceptSock == -1)
{
printf("accept socket failed!\r\n");
continue;
}
read(nAcceptSock,sRecvBuffer,500);
printf("Recv :%s\r\n",sRecvBuffer);
/*生成日志分析文件*/

/*日志文件处理,返回分析结果*/


/*向F5服务器反馈分析结果*/
strcpy(sSendBuffer,"receive successful!");
send(nAcceptSock,sSendBuffer,500,0);
}
}
return(0);
}



客户端:
main(argc, argv)
int argc;
char *argv[];
{
struct sockaddr_in ClientAddr;
int nConnectSock = 0;
int nread;
int n = 0;
char sSendBuffer[100];
char sRecvBuffer[100];
fd_set socks; /*套接字描述符集*/

  if((nConnectSock = socket(AF_INET,SOCK_STREAM,0)) == -1)
  {
  printf("Create socket error:%s\r\n",strerror(errno));
return -1;
  }
  
  bzero(&ClientAddr,sizeof(ClientAddr));
  ClientAddr.sin_family = AF_INET;
  ClientAddr.sin_port = htons(1043);
  inet_pton(AF_INET, "127.0.0.1", &ClientAddr.sin_addr);
  
  if(connect(nConnectSock,(struct sockaddr *)&ClientAddr,sizeof(ClientAddr)) < 0)
  {
  printf("Connect socket error:%s\r\n",strerror(errno));
  return -1;
  }
  while(1)
  {
  memset(sSendBuffer,0,500);
  memset(sRecvBuffer,0,500);


  FD_ZERO(&socks);
  FD_SET(nConnectSock,&socks);
  FD_SET(0,&socks);
 
  select(nConnectSock+1,&socks,NULL,NULL,NULL);
  if(FD_ISSET(nConnectSock,&socks))
  {
  nread = recv(nConnectSock,sRecvBuffer,500,0);
  printf("Recv:%s\r\n",sRecvBuffer);
  }
  if(FD_ISSET(0,&socks))
  {
  nread = read(0,sSendBuffer,500);
  send(nConnectSock,sSendBuffer,500,0);
  }
  } 
  return(0);
}



运行情况如下:
服务器端:
n2 = 1
Recv :hello

n1 = 2
select socket error:0
n1 = 3
select socket error:0
n1 = 4
select socket error:0


客户端:
hello
Recv:receive successful!
hi
hello too




问题:
服务器端第一次调用select函数能监听到客户端的请求,返回值大于0。当客户端从第二次开始发送信息时,服务器端select返回的值都是0,为什么?


[解决办法]
服务器端:
select(nLsnSock+1,&socks,NULL,NULL,&recvtime); /*阻塞*/

上边一句有问题,查手册,在接收连接后,就不是nLsnSock+1了
应该是nAcceptSock+1,自己想想为什么

一般得是这样
int maxSockID(最好全局的)
开始用maxSockID = nLsnSock;
然后select(maxSockID+1,&socks,NULL,NULL,&recvtime); /*阻塞*/

当有新的连接到来时
nAcceptSock = accept(nLsnSock,...)成功后
然后maxSockID = nAcceptSock;


[解决办法]
楼主,tcp连接在accept后返回那个描述才应该被用来被监听。

你直接监听socket返回的描述符是不对的。
[解决办法]

探讨
对于1楼:
已经按你说的去改了,可是问题仍然存在。
修改如下:
nMaxSock = nLsnSock;
/*循环监听F5请求*/
while(1)
{
。。。。。。。。
nReady = select(nMaxSock+1,&amp;socks,NULL,NULL,&amp;recvtime); /*阻塞*/
...........
nAcceptSock = accept(……

热点排行