为什么我的 select() 不能接受新客户端?
Why is my select() cannot accept a new client ?
我正在做一个在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 本地主机端口)将客户端连接到服务器时the select()
调用仍然没有返回任何内容。
这在 Unix 版本上运行良好。
我还注意到socket
调用返回的文件描述符非常高,优于 250,正常吗?在 Unix 上,它总是返回一个低于 de 5 的文件描述符。
我相信您也可以将s_addr
设置为零,以便它将套接字绑定到所有可用地址或显式htonl(0x7f000001)
"127.0.0.1"。 "本地主机"的定义可能令人惊讶。 - D.肖利
@D.肖利 你是对的,我把s_addr
设置为 0,这有效! – 迪米特里·达尼洛夫
相关文章:
- "xshared_expression"不能接受xfunction表达式
- 节点.js到 c++ 客户端:不接收来自 socket.emit 的消息
- 为什么此参数包不能接受函数指针?
- 如何在C++中创建OpenVPN客户端?(不是 TUN/Tap 管理器,而是真正的客户端)
- Dtls 客户端不会使用 cookie 发送 ClientHello(英语:ClientHello)
- istringstream-function string_to_int不能接受C-STR,为什么
- UDP 客户端不会在 esp32 上广播消息
- 为什么 std:map 不能接受指针作为键值?
- C++:强制实施函数,使其不能接受按值传递的任何参数
- 我不能接受getline
- 为什么我的 select() 不能接受新客户端?
- 如果您不编写 Web 应用程序,并且您的客户端不是浏览器,那么 Web 套接字相对于常规套接字的优势是什么?
- 为什么"auto"在推导返回值时不能接受大括号的初始化列表?
- 使基类函数对客户端不可见
- 我必须编写一个FTP客户端.不知道从哪里开始.C++
- 什么不能接受字符串向量并用 offest 和 assigmnet 运算符替换任何字符串的字符?
- ZeroMQ C#客户端不接收来自C++服务器的消息
- 为什么 std::function 不能接受推导类型作为其模板参数
- "官方"CUDA 减少功能不能接受某些数字?
- 枚举类型不能接受 CIN 命令