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.
I believe that you can also set the
s_addr
to zero so that it binds the socket to all available addresses or tohtonl(0x7f000001)
for "127.0.0.1" explicitly. The definition of "localhost" can be surprising. – D.Shawley@D.Shawley You were right, i set
s_addr
to 0 and that worked ! – Dimitri Danilov