如果我在另一个线程中将 tcp 套接字更改为非阻塞,我的程序 returns 1 在 Sleep() 之后
My program returns 1 after Sleep() if I change a tcp socket to non blocking in a different thread
我有一个线程接受客户端连接并使客户端套接字非阻塞。
for(char Index = 0; Index < MAX_CLIENTS; ++Index)
{
if(ClientSockets[Index] == INVALID_SOCKET)
{
accept(ClientSockets[Index], (sockaddr *)&Address, &AddressSize);
unsigned long iMode = 1;
if(ioctlsocket(ClientSockets[Index], FIONBIO, &iMode) != NO_ERROR)
{
Error("Making client socket unblocking has failed.\n");
}
}
}
在主线程中,我从客户端接收数据包。
在我执行 Sleep() 后的主线程中,程序 returns 1 结束。
我发现唯一有用的是从接受客户端的线程中删除 ioctlsocket。
您使用 accept()
不正确。
accept()
的第一个参数是一个仅供输入的参数,指定要为哪个 侦听套接字 接受挂起的客户端连接。该参数不是输出参数,就像您试图将其视为一样。
您正在将 ClientSockets[Index]
传递给第一个参数 accept()
。但是 ClientSockets[Index]
设置为 INVALID_SOCKET
。这将使 accept()
失败,但您忽略了该错误。您需要传入之前使用 socket()
创建的 listening socket。
您没有将 accept()
的 return 值 分配给 ClientSockets[Index]
,因此它仍设置为 INVALID_SOCKET
。然后将其传递给 ioctlsocket()
的第一个参数,这将失败。您确实检查了该错误,但没有报告失败的原因,否则您会知道由于传递了无效的套接字而失败,错误代码为 WSAENOTSOCK
(10038)。
尝试更像这样的东西:
for(char Index = 0; Index < MAX_CLIENTS; ++Index)
{
if (ClientSockets[Index] == INVALID_SOCKET)
{
AddressSize = sizeof(Address);
ClientSockets[Index] = accept(serverSocket, (sockaddr *)&Address, &AddressSize);
if (ClientSockets[Index] != INVALID_SOCKET)
{
unsigned long iMode = 1;
if (ioctlsocket(ClientSockets[Index], FIONBIO, &iMode) != SOCKET_ERROR)
{
Error("Making client socket unblocking has failed.\n");
closesocket(ClientSockets[Index]);
ClientSockets[Index] = INVALID_SOCKET;
continue;
}
// use ClientSockets[Index] as needed ...
}
}
}
或者:
AddressSize = sizeof(Address);
SOCKET clientSocket = accept(serverSocket, (sockaddr *)&Address, &AddressSize);
if (clientSocket != INVALID_SOCKET)
{
unsigned long iMode = 1;
if (ioctlsocket(clientSocket, FIONBIO, &iMode) != SOCKET_ERROR)
{
Error("Making client socket unblocking has failed.\n");
closesocket(clientSocket);
}
else
{
int Index;
for(Index = 0; Index < MAX_CLIENTS; ++Index)
{
if (ClientSockets[Index] == INVALID_SOCKET)
break;
}
if (Index == MAX_CLIENTS)
{
Error("No room for client socket.\n");
closesocket(clientSocket);
}
else
{
ClientSockets[Index] = clientSocket;
// use clientSocket as needed ...
}
}
}
我有一个线程接受客户端连接并使客户端套接字非阻塞。
for(char Index = 0; Index < MAX_CLIENTS; ++Index)
{
if(ClientSockets[Index] == INVALID_SOCKET)
{
accept(ClientSockets[Index], (sockaddr *)&Address, &AddressSize);
unsigned long iMode = 1;
if(ioctlsocket(ClientSockets[Index], FIONBIO, &iMode) != NO_ERROR)
{
Error("Making client socket unblocking has failed.\n");
}
}
}
在主线程中,我从客户端接收数据包。
在我执行 Sleep() 后的主线程中,程序 returns 1 结束。
我发现唯一有用的是从接受客户端的线程中删除 ioctlsocket。
您使用 accept()
不正确。
accept()
的第一个参数是一个仅供输入的参数,指定要为哪个 侦听套接字 接受挂起的客户端连接。该参数不是输出参数,就像您试图将其视为一样。
您正在将 ClientSockets[Index]
传递给第一个参数 accept()
。但是 ClientSockets[Index]
设置为 INVALID_SOCKET
。这将使 accept()
失败,但您忽略了该错误。您需要传入之前使用 socket()
创建的 listening socket。
您没有将 accept()
的 return 值 分配给 ClientSockets[Index]
,因此它仍设置为 INVALID_SOCKET
。然后将其传递给 ioctlsocket()
的第一个参数,这将失败。您确实检查了该错误,但没有报告失败的原因,否则您会知道由于传递了无效的套接字而失败,错误代码为 WSAENOTSOCK
(10038)。
尝试更像这样的东西:
for(char Index = 0; Index < MAX_CLIENTS; ++Index)
{
if (ClientSockets[Index] == INVALID_SOCKET)
{
AddressSize = sizeof(Address);
ClientSockets[Index] = accept(serverSocket, (sockaddr *)&Address, &AddressSize);
if (ClientSockets[Index] != INVALID_SOCKET)
{
unsigned long iMode = 1;
if (ioctlsocket(ClientSockets[Index], FIONBIO, &iMode) != SOCKET_ERROR)
{
Error("Making client socket unblocking has failed.\n");
closesocket(ClientSockets[Index]);
ClientSockets[Index] = INVALID_SOCKET;
continue;
}
// use ClientSockets[Index] as needed ...
}
}
}
或者:
AddressSize = sizeof(Address);
SOCKET clientSocket = accept(serverSocket, (sockaddr *)&Address, &AddressSize);
if (clientSocket != INVALID_SOCKET)
{
unsigned long iMode = 1;
if (ioctlsocket(clientSocket, FIONBIO, &iMode) != SOCKET_ERROR)
{
Error("Making client socket unblocking has failed.\n");
closesocket(clientSocket);
}
else
{
int Index;
for(Index = 0; Index < MAX_CLIENTS; ++Index)
{
if (ClientSockets[Index] == INVALID_SOCKET)
break;
}
if (Index == MAX_CLIENTS)
{
Error("No room for client socket.\n");
closesocket(clientSocket);
}
else
{
ClientSockets[Index] = clientSocket;
// use clientSocket as needed ...
}
}
}