while(TRUE)
{
select(0,&readSet,NULL,NULL,&readtime);
if (FD_ISSET(Server,&readSet))
  {
  for(i=0;i<10;i++)
   {
    if (!client[i])
     {
      client[i]=accept(Server,(sockaddr *)&clienthome,(int *)&addrlen);
      break;
     }
    }
if (client[i]==-1)
continue; 
   }
ioctlsocket(client[i],FIONBIO,(unsigned long *)&ul); //为非阻塞
FD_SET(client[i],&readSet);
int len;
char buf[120];

for(i=0;i<10;i++)
{
if (FD_ISSET(client[i],&readSet))
{
len=recv(client[i],buf,100,0);
if (len==-1)
continue;
buf[len]=0;
send(client[i],buf,len,0);
break;
}
} }
前面就不写了,就是创建一个Server socket,FD_SET(Server,&readSet);
..
这段代码有什么问题,为什么readSet中始终没有把全部的client都加入?

解决方案 »

  1.   

    没看懂?
    FD_SET(client[i],&readSet);
    之后就直接recv?
      

  2.   

    那应该怎么写,我是第一次用select呀,不太理解
      

  3.   

    没看懂?
    FD_SET(client[i],&readSet);
    之后就直接recv?
    后还要加select(0,&readSet,0,0,..)吗?
      

  4.   

    要加select(0,&readSet,0,0,..)
    它可以监测FD_READ事件
      

  5.   

    而且你的程序
    FD_SET(client[i],&readSet);是在循环外面,只加了一个socket到readSet里面?
      

  6.   

    FD_ZERO(&readSet);
    for(i=0;i<ClientCount;i++)
      FD_SET(client[i],&readSet);
    select(0,&readSet,NULL,&readSet,&readtime);
    for(i=0;i<ClientCount;i++)
    {
      if (FD_ISSET(client[i],&readSet))
      {
          ......
      }
    }
      

  7.   

    我的本意是:
    1.最开始只要有客户端连接,因为Server已经在readSet中,所以往下走,然后把建立连接的client[0]加入readSet中,这时readSet中应该有Server,client[0],然后又回到select处等待,
    2.这时如果还有客户端请求连接,FD_ISSERT判断Server在readSet中,然后用client[1]连接这个客户,把client[1]加入readSet,readSet中应该有Server,client[0],client[1],可是client[1]能进入readSet,但调试时发现client[1]不是占了Server的位置就是占了client[0]的位置,也就是说readSet中始终只有两个元素
    3.如果新的客户端连接,client[0]所连接的客户发了数据过来,select中被触发,FD_ISSERT判断不是Server产生的,往下走到第二个FD_ISSERT中,轮询发现client[0]在里面,于是就往下处理我感觉我对select的理解有些问题,所以写的详细一些,请大家指点
      

  8.   

    readtime要设置!select要判断返回值
      

  9.   

    连接多个客户,必须有多个socket与客户一对一连接
      

  10.   

    select返回了之后,有信号的socket被放在readSet里,其它的全没了

    readSet中有server,client[0],其中server有信号,select返回之后readSet中就只有server了
      

  11.   

    所以一个循环之前要全部重新FD_SET
      

  12.   

    不推荐这种做法,效率差。
    错误处理自己做ClientCount = 0;
    while(TRUE)
    {
      FD_ZERO(&readSet);
      FD_SET(Server, &readSet);
      for(i=0;i<ClientCount;i++)
        FD_SET(client[i], &readSet);  ret = select(0,&readSet,NULL,&readSet,&readtime);
      if(ret == SOCKET_ERROR)
      {
        //error
      }
      if(ret == 0)
      {
        continue; //time out
      }  //check client socket
      int len;
      char buf[120];

      for(i=0;i<ClientCount;i++)
      {
        if (FD_ISSET(client[i],&readSet))
        {
          len=recv(client[i],buf,100,0);
          if (len==-1)
            continue;
          buf[len]=0;
          send(client[i],buf,len,0);
        }
      }  //check server socket
      if (FD_ISSET(Server,&readSet))
      {
        if (ClientCount < MAX_CLIENT)
        {
          client[ClientCount] = accept(Server,(sockaddr *)&clienthome,(int *)&addrlen);
          ClientCount++;
         }
      }
    }//end while
      

  13.   

    那应该如何处理?用多线程?用事件通知,异步消息,难道select只能这样做吗?
      

  14.   

    我有多线程的,但现在是这样处理的,一个socket连接起一个线程,这样好象更不好,如果有几千个socket连接,系统资料肯定不够