我正在做一个在Linux和Windows上运行的网络抽象。
要创建服务器套接字,请执行以下操作:
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;
}
我在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);
然后我用这种方式选择:
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);
问题是,select()
函数阻塞(我知道这是正常的)但是当我通过windows telnet(telnet localhost port)the select()
调用将客户端连接到服务器时仍然没有返回任何东西。
这在Unix版本上运行良好。
我还注意到socket
调用返回的文件描述符非常高,优于250,这是正常的吗?在Unix上,它总是返回一个低于de 5的文件描述符。
答案 0 :(得分:0)
我相信您也可以将s_addr
设置为零,以便将套接字绑定到所有可用地址,或者将套接字绑定到htonl(0x7f000001)
上的“ 127.0.0.1”。 “ localhost”的定义可能令人惊讶。
– D.Shawley
@ D.Shawley你是对的,我将s_addr
设置为0,那行得通!
–Dimitri Danilov