我有一个程序,它正在侦听端口 200。客户端连接到它后,从客户端接收到的所有数据都将写入 std::cout。如果从客户端获取数据时发生任何错误,我想重新启动托管。
ServerSocket sock;
while(true)
{
try
{
uint8 buff[1000];
std::cout << "hosting..." << std::endl;
sock.Host(port);
while(true)
{
size_t ret = sock.GetData(buff, 1000);
buff[ret] = '\0';
std::cout << buff << std::endl;
}
}
catch(const SocketException& se)
{
std::cout << se.What() << std::endl;
}
}
我第一次连接到这个一切都很好。如果我关闭客户端,则会发生 SocketException(因此开始新的托管)。
主机功能:
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
m_address.sin_family = AF_INET;
m_address.sin_port = htons(port);
m_address.sin_addr.S_un.S_addr = INADDR_ANY;
int optval = 1;
setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(int));
int retval = bind(m_socket, reinterpret_cast<sockaddr*>(&m_address), sizeof(m_address));
if(retval == SOCKET_ERROR)
throw SocketException("bind() error", __FUNCTION__, WSAGetLastError());
retval = listen(m_socket, SOMAXCONN);
if(retval == SOCKET_ERROR)
throw SocketException("listen() error", __FUNCTION__, WSAGetLastError());
m_socket = accept(m_socket, NULL, NULL);
if(m_socket == INVALID_SOCKET)
throw SocketException("accept() error", __FUNCTION__, WSAGetLastError());
我需要 setsockopt 行,因为我想在发生错误后立即绑定(并且最后一个托管套接字处于 TIME_WAIT 状态?)。没有 setsockopt 我有 bind() 错误。所以我使用 setsockopt,它让我在端口上托管没有问题。但是,当我再次启动客户端并尝试连接到主机时,没有发生错误,我可以再次发送数据。但是程序不接受任何传入连接(它仍然停留在 accept(m_socket, NULL, NULL); 等待传入连接的行)。我假设客户端可以以某种方式连接到旧套接字。那可能吗?
(注意:如果我添加 WSACleanup(); WSAStartup(MAKEWORD(2, 2), &m_wsaData); 行到主机函数,那么一切都按预期工作。我不知道为什么。WSACleanup();WSAStartup(MAKEWORD(2 , 2), &m_wsaData); 仅在我为调查此问题而制作的示例程序中帮助我。在原始程序中,2 行不起作用。)