DWORD WINAPI netProc(LPVOID pParam)
  {
  int i = 0;
  PArmTheadParam  montp;
  montp = (PArmTheadParam)pParam;
  int res;   
  char recvBuf[100];   
  while (!b_stopFlag) 
  {
  for(i = 0;i < montp->GunNum ; i++)
  {
  fd_set fdRead;
  timeval   mWaitTime;
  
  mWaitTime.tv_sec = 1;
  mWaitTime.tv_usec = 0;
  memset(recvBuf,0,100);
  memset(Buf,0,250);
  
  FD_ZERO(&fdRead);
  FD_SET(montp->s[i],&fdRead);
  res = select((montp->s[i])+1,&fdRead,NULL,NULL,&mWaitTime);
  if(res > 0)
  {
  if(FD_ISSET(montp->s[i],&fdRead))
  {
  recv(montp->s[i],recvBuf,22,0);
  GUNSTATE GunState;
  memcpy(&GunState,recvBuf+17,5);
  //如果任何一个模块有异常,则返回模块异常
  if((GunState. mGS[0].MState== 0) || (GunState.mGS[1].MState == 0)|| (GunState.mGS[2].MState == 0) || (GunState.mGS[3].MState == 0))
  {
  //   closesocket(montp->s[i]);
  //   WSACleanup();
  COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
  cpd.dwData = GUN_MSTATE_ERROR;      
  cpd.cbData = 4;
  cpd.lpData = (PVOID)&(montp->beginAddr[i]);
  SendMessage(montp->recvHd,WM_COPYDATA,(WPARAM)(montp->threadHd),(LPARAM)&cpd);//消息处理函数
  }
  
  if(recvBuf[10] == 0x01)
  {
  COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
  cpd.dwData = GUN_GATE_CHANGED;
  cpd.cbData = 4;
  cpd.lpData = (PVOID)&(montp->beginAddr[i]);
  
  SendMessage(montp->recvHd,WM_COPYDATA,(WPARAM)(montp->threadHd),(LPARAM)&cpd);
  } 
  if(recvBuf[10] == 0x02)
  {
  int j ,k;
  for(j = 0 ;j < 4 ; j++)
  {
  for(k = 0 ; k < 6;k++)
  {
  // memcpy(Buf+30*j+5*k,&(montp->beginAddr[i]),4);
  Buf[30*j+5*k] = (char)((montp->beginAddr[i]) &  0xff);
  Buf[30*j+5*k+1] = (char)(((montp->beginAddr[i])>>8)& 0xff);
  Buf[30*j+5*k+2] = (char)(((montp->beginAddr[i])>>16)& 0xff);
  Buf[30*j+5*k+3]   = (char)(((montp->beginAddr[i])>>24)& 0xff);
  
  Buf[30*j+5*(k+1)-1] = (GunState.mGS[j].GS >> k)& 1;
  montp->beginAddr[i]++;
  }
  }
  montp->beginAddr[i] = montp->beginAddr[i] - 24 ;
  
  if(montp->recvHd != NULL)
  {
  COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
  cpd.dwData = GUN_STATUS_CHANGED;      
  cpd.cbData = 120;
  cpd.lpData = (PVOID)Buf;
  SendMessage(montp->recvHd,WM_COPYDATA,(WPARAM)(montp->threadHd),(LPARAM)&cpd);//消息处理函数
  }
  }  
  }
  }
  Sleep(100);
  }
  }
  COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
  cpd.dwData = MSG_COPYDATA_STOP;      
  cpd.cbData = 0;
  cpd.lpData = NULL;
  SendMessage(montp->recvHd,WM_COPYDATA,(WPARAM)(montp->threadHd),(LPARAM)&cpd);
  b_threadRunning = FALSE;
  CloseHandle(hThread);
  
  for(i = 0;i < montp->GunNum;i++)
  {
  closesocket(montp->s[i]);
  }
  WSACleanup();
  ExitThread(0);
  return 0;
}  NETGUNCABDLL_API int NetStartMonitor(unsigned long *netIp, unsigned short netPort,int GunNum,unsigned long *beginAddr,HWND recvHd ,HANDLE *threadHd)
  {
  DWORD tId;
  PArmTheadParam pMontp; // 设置传入参数
  
  pMontp = new _ArmThreadParam;
  pMontp->GunNum = GunNum;
  pMontp->netPort = netPort;
  pMontp->recvHd = recvHd;
  
  int i;
  for(i = 0;i < GunNum; i++)
  {
  pMontp->netIp[i] = netIp[i];
  pMontp->beginAddr[i] = beginAddr[i];
  }
  
  WORD wVersionRequested;
  WSADATA wsaData;
  int err;
  wVersionRequested = MAKEWORD(2,2); //初始化socket链接的版本号
  err = WSAStartup( wVersionRequested, &wsaData );
  if ( err != 0 ) 
  {
  return STARTUP_FAILED;
  }
  if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 ) 
  {
  WSACleanup();
  return VERSION_FAILED; 
  }
  
  SOCKET s[256];
  
  for(i = 0;i < GunNum;i++)
  {
  if((s[i] = socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR)  //生成SOCKET
  {
  closesocket(s[i]);
  WSACleanup();
  return CREATESOCKET_ERROR;
  }
  SOCKADDR_IN addrSrv;
  addrSrv.sin_addr.S_un.S_addr = netIp[i];
  addrSrv.sin_family = AF_INET;
  addrSrv.sin_port = htons(netPort);
  
  if(connect(s[i],(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)) == SOCKET_ERROR) //连接socket
  {
  closesocket(s[i]); 
  WSACleanup();
  return CONNECT_ERROR;
  }
  pMontp->s[i] = s[i];
  }
  
  *threadHd = CreateThread(NULL,0,netProc,(LPVOID)pMontp,CREATE_SUSPENDED,&tId); //线程挂起
  if(*threadHd == NULL)
  {
  return CREATE_THREAD_FAILED;
  }
  
  pMontp->threadHd = *threadHd;
  b_threadRunning = true;
  
  ResumeThread(*threadHd); // 线程运行
  
  delete pMontp;
  return 0;
  }
我这是一个线程中希望调用select判断是否有数据可读的情况,按照需要由于需要轮询多个socket,所以设置了超时,但是我始终不能接收到数据,希望高手指教一下,这个函数哪里除了问题。

解决方案 »

  1.   

    首先,我看你的程序中有一段:
      if(connect(s[i],(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)) == SOCKET_ERROR) //
      {
      closesocket(s[i]); 
      WSACleanup();
      return CONNECT_ERROR;
      }
    那么连接中如果出现错误,那么线程函数就不会调用,你调试以下看看这里是否出现了问题
      

  2.   

    试试这个:
    while (true) 
    {
       FD_SET SocketSet;
       SocketSet.fd_count = 5;//这里是你的连接数
       SocketSet.fd_array[1,2,3,4,5] = yousocket;//5个
       int Ret = select(0, &SocketSet,NULL,NULL,NULL);
       ......
       FD_ISSET(yousocket, &SocketSet);
       .....
    }
      

  3.   

    wzbhbb(灯火阑珊) 的方法可以同时盯着5个socket。理论上可以同时盯着64个。如果要轮训更多的,则把超时设成0:
    mWaitTime.tv_sec = 0;
    mWaitTime.tv_usec = 0;但是这样又带来问题,所有的SOCKET轮训后如果立即又轮训,那么CPU是不是占用太多?如果超时不设成0,则轮训总汇带来等待。