Why is my select() cannot accept a new client ?

79 views Asked by At

I am doing a network abstraction that runs in Linux and Windows.

To create the server socket I do this :

int TCPSocket::create(unsigned int port)
{
  _type = SERVER;
  char *ip;
  int error;

  _sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  if (_sock == INVALID_SOCKET)
  {
    std::cerr <<"Winsock error - Socket creation Failed!\n" << std::endl;
    throw std::exception();
  }

  _sockAddr.sin_family = AF_INET;
  _sockAddr.sin_port = htons(port);
  hostent* thisHost;
  thisHost = gethostbyname("");
  ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
  _sockAddr.sin_addr.s_addr = inet_addr(ip);

  error = bind(_sock, (SOCKADDR *) &_sockAddr, sizeof(SOCKADDR));
  if (error == SOCKET_ERROR)
  {
    std::cerr << "bind() failed with error:  " << WSAGetLastError() << std::endl;
    closesocket(_sock);
    WSACleanup();
    throw std::exception();
  }

  error = listen(_sock, 1);
  if (error == SOCKET_ERROR)
  {
    std::cerr << "listen() failed with error:  " << WSAGetLastError() << std::endl;
    closesocket(_sock);
    WSACleanup();
    throw std::exception();
  }
  return _sock;
}

I push this socket in my vector of TCPSocket

  error = WSAStartup(MAKEWORD(2,2), &_wsaData);
  if (error)
  {
    std::cerr << "WSAStartup() failed with error:" << error << std::endl;
    throw std::exception();
  }
  TCPSocket *servSock = new TCPSocket();
  int fdCreated = servSock->create(_port);
  _fdList.push_back(servSock);

Then I use select this way :

  fd_set fd_read;

  fd_set fd_write;
  int fdMax;
  int i = 0;
  int selectRet;

  FD_ZERO(&fd_read);
  FD_ZERO(&fd_write);
  fdMax = 0;
  for (ISocket *tmpSock: _fdList)
  {
    TCPSocket *socket = reinterpret_cast<TCPSocket *>(tmpSock);
    if (socket->getType() != TCPSocket::FREE)
    {
      FD_SET(socket->getSock(), &fd_read);
      FD_SET(socket->getSock(), &fd_write);
      fdMax = socket->getSock();
    }
    i++;
  }
  if ((selectRet = select(fdMax + 1, &fd_read, &fd_write, NULL, NULL)) == -1)
  {
    perror("select");
    throw std::exception();
  }
  std::cout << "good" << std::endl;
  std::cout << selectRet << std::endl;
  if (selectRet > 0)
    this->eventAction(fd_read, fd_write);

Problem is, the select() function is blocking (it is normal I know that) but when I connect a client to the server by the way of the windows telnet (telnet localhost port) the select() call still doesn't return anything.

This is working fine on Unix version.

I also noticed that the file descriptor returned by the socket call is very high, it is superior to 250, is it normal ? On Unix it returns always a file descriptor inferior de 5.

1

There are 1 answers

0
Armali On

I believe that you can also set the s_addr to zero so that it binds the socket to all available addresses or to htonl(0x7f000001) for "127.0.0.1" explicitly. The definition of "localhost" can be surprising. – D.Shawley

@D.Shawley You were right, i set s_addrto 0 and that worked ! – Dimitri Danilov