select 实现超时连接

int ConnectHasTimeout(SOCKET sock, const sockaddr *name, int namelen, int nsec)
{
 int n;
 int error = 0;
 unsigned long flag = 1;
 ioctlsocket(sock, FIONBIO, (unsigned long*)&flag);
 if ((n = connect(sock, name, namelen)) == SOCKET_ERROR)
 {
  if (WSAEINPROGRESS == WSAGetLastError())
  {
   return -1;
  }
 }

 do
 {
  if (0 == n)
  {
   break;
  }

  struct timeval tv;
  fd_set rset, wset;
  FD_ZERO(&rset);
  FD_SET(sock, &rset);
  wset = rset;
  tv.tv_sec = nsec;
  tv.tv_usec = 0;

  if ((n = select(0, &rset, &wset, 0, nsec ? &tv : NULL)) == 0)
  {
   closesocket(sock);
   WSASetLastError(WSAETIMEDOUT);
   return -1;
  }

  if (FD_ISSET(sock, &rset) || FD_ISSET(sock, &wset))
  {
   int len = sizeof(error);
   if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&error, &len) < 0)
   {
    return -1;
   }
  }
 }while (0);
 
 flag = 0;
 ioctlsocket(sock, FIONBIO, (unsigned long*)&flag);
 if (error)
 {
  closesocket(sock);
  return -1;
 }
 return 0;
}

你可能感兴趣的:(select 实现超时连接)