gpt4 book ai didi

c++ - Winsock C++ 连接超时

转载 作者:行者123 更新时间:2023-11-27 23:51:29 25 4
gpt4 key购买 nike

我正在尝试为 connect() 函数设置我自己的时间。

我的代码适用于默认连接,如下所示:

bool connectFUNC4(char * ipaddr) {

WSADATA wsa;
struct sockaddr_in server;

if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return false;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
return false;

server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_family = AF_INET;
server.sin_port = htons(5577);

if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
return false;
return true;
}

我理解阻塞和非阻塞连接的想法,并且我找到了设置为非阻塞模式和超时的解决方案。它总是成功完成,但通信不起作用。

bool connectFUNC3(char * ipaddr) {

WSADATA wsa;
struct sockaddr_in server;

server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_family = AF_INET;
server.sin_port = htons(5577);

unsigned long block = 1;
ioctlsocket((unsigned int)sock, FIONBIO, &block);

WSAGetLastError();

int ret = connect(sock, (struct sockaddr *)&server, sizeof(server));
timeval time_out;
time_out.tv_sec = 5;
time_out.tv_usec = 0;

fd_set setW, setE;

FD_ZERO(&setW);
FD_SET(sock, &setW);
FD_ZERO(&setE);
FD_SET(sock, &setE);
select(0, NULL, &setW, &setE, &time_out);

bool flag;

if (FD_ISSET(sock, &setW))
{
// connection successful
flag = true;
}
else if (FD_ISSET(sock, &setE))
{
// connection fail
flag = false;
}
else
{
// connection timeout
flag = false;
}

block = 0;
ioctlsocket((unsigned int)sock, FIONBIO, &block);
return flag;
}

请帮助让它工作,或找到另一个解决方案(多线程在我的情况下不可用)。谢谢。

最佳答案

您的两个函数都没有检查任何返回值是否有错误。当以非阻塞模式调用 select() 时,只有当 connect()WSAEWOULBLOCK 错误而失败时才调用它,如果 select() 然后返回 > 0 那么你应该首先检查 setE 而不是 setW

尝试更像这样的东西:

void closesock(SOCKET *s)
{
// preserve current error code
int err = WSAGetLastError();
closesocket(*sock);
*sock = INVALID_SOCKET;
WSASetLastError(err);
}

bool connectFUNC4(char * ipaddr)
{
// you really shouldn't be calling WSAStartup() here.
// Call it at app startup instead...

struct sockaddr_in server = {0};
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_port = htons(5577);

// ipaddr valid?
if (server.sin_addr.s_addr == INADDR_NONE)
return false;

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
return false;

if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
// connection failed
closesock(&sock);
return false;
}

// connection successful

return true;
}

bool connectFUNC3(char * ipaddr)
{
// you really shouldn't be calling WSAStartup() here.
// Call it at app startup instead...

struct sockaddr_in server = {0};
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_port = htons(5577);

// ipaddr valid?
if (server.sin_addr.s_addr == INADDR_NONE)
return false;

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
return false;

// put socked in non-blocking mode...
u_long block = 1;
if (ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR)
{
closesock(&sock);
return false;
}

if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
// connection failed
closesock(&sock);
return false;
}

// connection pending

fd_set setW, setE;

FD_ZERO(&setW);
FD_SET(sock, &setW);
FD_ZERO(&setE);
FD_SET(sock, &setE);

timeval time_out = {0};
time_out.tv_sec = 5;
time_out.tv_usec = 0;

int ret = select(0, NULL, &setW, &setE, &time_out);
if (ret <= 0)
{
// select() failed or connection timed out
closesock(&sock);
if (ret == 0)
WSASetLastError(WSAETIMEDOUT);
return false;
}

if (FD_ISSET(sock, &setE))
{
// connection failed
int err = 0;
getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, sizeof(err));
closesock(&sock);
WSASetLastError(err);
return false;
}
}

// connection successful

// put socked in blocking mode...
block = 0;
if (ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR)
{
closesock(&sock);
return false;
}

return true;
}

关于c++ - Winsock C++ 连接超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46045434/

25 4 0
文章推荐: c++ - 当我遇到错误的 constexpr if branch 时停止 visual studio 17 编译
文章推荐: javascript - 访问
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com