gpt4 book ai didi

c++ - 在非阻塞套接字中选择函数

转载 作者:行者123 更新时间:2023-11-30 04:02:38 26 4
gpt4 key购买 nike

我正在构建一个在线游戏客户端,当我尝试连接到离线服务器时,我的客户端卡住了,所以我想使用适合游戏的非阻塞套接字,因为在连接到服务器时还需要​​完成其他任务.

当使用非阻塞套接字时,connect 函数总是返回相同的值,不管结果如何,所以这里的人推荐使用 select 函数来查找结果连接请求。

(连接前设置非阻塞套接字)

u_long iMode=1;
ioctlsocket(hSocket,FIONBIO,&iMode);

(设置套接字集)

FD_ZERO(&Write);
FD_ZERO(&Err);
FD_SET(hSocket, &Write);
FD_SET(hSocket, &Err);

TIMEVAL Timeout;

int TimeoutSec = 10; // timeout after 10 seconds
Timeout.tv_sec = TimeoutSec;
Timeout.tv_usec = 0;
int iResult = select(0, //ignored
NULL, //read
&(client.Write), //Write Check
&(client.Err), //Error Check
&Timeout);

if(iResult)
{
}
else
{
message_login("Error","Can't connect to the server");
}

select 函数总是返回 -1,为什么?

最佳答案

select() 返回 -1 (SOCKET_ERROR) 时,使用 WSAGetLastError() 找出失败的原因。

如果套接字在 select() 退出时设置的 Err 中,使用 getsockopt(SOL_SOCKET, SO_ERROR) 检索套接字错误告诉您为什么 connect() 失败的代码。

if(iResult) 对任何非零值(包括 -1)的计算结果为真。您需要改用 if(iResult > 0),因为 iResult 将报告在 any fd_set 中发出信号的套接字数量,0 表示超时,-1 表示失败。

尝试更像这样的东西:

u_long iMode = 1;
if (ioctlsocket(hSocket, FIONBIO, &iMode) == SOCKET_ERROR)
{
int errCode = WSAGetLastError();
// use errCode as needed...
message_login("Error", "Can't set socket to non-blocking, error: ..."); // however you supply a variable value to your message...
}

if (connect(client.hSocket, ...) == SOCKET_ERROR)
{
int errCode = WSAGetLastError();
if (errCode != WSAEWOULDBLOCK)
{
// use errCode as needed...
message_login("Error", "Can't connect to the server, error: ..."); // however you supply a variable value...
}
else
{
// only in this condition can you now use select() to wait for connect() to finish...
}
}

TIMEVAL Timeout;

int TimeoutSec = 10; // timeout after 10 seconds
Timeout.tv_sec = TimeoutSec;
Timeout.tv_usec = 0;

int iResult = select(0, //ignored
NULL, //read
&(client.Write), //Write Check
&(client.Err), //Error Check
&Timeout);

if (iResult > 0)
{
if (FD_ISSET(client.hSocket, &(client.Err)))
{
DWORD errCode = 0;
int len = sizeof(errCode);
if (getsockopt(client.hSocket, SOL_SOCKET, SO_ERROR, (char*)&errCode, &len) == 0)
{
// use errCode as needed...
message_login("Error", "Can't connect to the server, error: ..."); // however you supply a variable value to your message...
}
else
message_login("Error", "Can't connect to the server, unknown reason");
}
else
message_login("Success", "Connected to the server");
}
else if (iResult == 0)
{
message_login("Error", "Timeout connecting to the server");
}
else
{
int errCode = WSAGetLastError();
// use errCode as needed...
message_login("Error", "Can't connect to the server, error: ..."); // however you supply a variable value to your message...
}

关于c++ - 在非阻塞套接字中选择函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24956235/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com