c++ - 如何使用 Winsock API 控制连接超时?

标签 c++ clr winsock

我正在使用 Winsock API 编写一个程序,因为一个 friend 想要一个简单的程序来检查并查看一个 Minecraft服务器是否正在运行。如果它正在运行,它工作正常,但是如果它没有运行,程序会卡住,直到我假设连接超时。另一个问题是,如果我有这样的东西(伪代码):

void connectButtonClicked()
{
     setLabel1Text("Connecting");
     attemptConnection();
     setLabel1Text("Done Connecting!");
}

它似乎直接跳到 attemptConnection(),完全忽略了上面的内容。我注意到这一点是因为程序会卡住,但不会将标签更改为“正在连接”。

这是我的实际连接代码:

bool CConnectionManager::ConnectToIp(String^ ipaddr)
{
    if(!m_bValid)
        return false;

    const char* ip = StringToPConstChar(ipaddr);
    m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(isalpha(ip[0]))
    {
        ip = getIPFromAddress(ipaddr);
    }
    sockaddr_in service;
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr(ip);
    service.sin_port = htons(MINECRAFT_PORT);
    if(m_socket == NULL)
    {
        return false;
    }
    if (connect(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)
    {
        closesocket(m_socket);
        return false;
    }
    else
    {
        closesocket(m_socket);
        return true;
    }

    return true;
}

在 CConnectionManager 的构造器中也有启动 Winsock API 等的代码。

那么,如何避免这种卡住,并允许我在连接期间更新进度条之类的东西?我必须在单独的线程中建立连接吗?我只在 Java 中使用过线程,所以我不知道该怎么做:/

此外:我正在使用 CLR Windows 窗体应用程序
我正在使用 Microsoft Visual C++ 2008 Express Edition

最佳答案

您的代码不会跳过标签更新。更新只涉及发出尚未处理的窗口消息,这就是为什么在连接套接字之前看不到新文本出现的原因。在连接套接字之前,您必须为新消息抽取消息队列。

不幸的是,对于套接字本身,WinSock API 中没有连接超时。您有两种选择来实现手动超时:

1) 假设您使用的是阻塞套接字(默认情况下套接字是阻塞的),请在单独的工作线程中执行连接。

2) 如果您不想使用线程,则将套接字切换到非阻塞模式。连接套接字总是会立即退出,所以你的主代码不会被阻塞,稍后你会收到连接成功与否的通知。有多种检测方法,具体取决于您使用的 API - WSAAsyncSelect()、WSAAsyncEvent() 或 select()。

无论哪种方式,当连接正在进行时,在您的主线程中运行一个计时器。如果连接成功,则停止计时器。如果计时器超时,则断开套接字,这将导致连接因错误而中止。

关于c++ - 如何使用 Winsock API 控制连接超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7780746/

相关文章:

c++ - 如何向 C 窗口中的几个对等点发送多播消息

c++ - 连续性多个 WSASend() io 完成端口

c++ - 在 main 中捕获 ifstream 异常

c++ - 带有参数的模板传递成员函数和返回值作为参数c++

c# - 在 .NET 4.0 中,值类型的 Equals 默认实现是什么?

c++ - 当我编译 CLR C++ 应用程序的 "release"版本时,除了 GUI 之外,还会弹出一个 cmd 窗口。我该如何解决这个问题?

c++ - 本地主机上的网络字节顺序

c++ - 在 Windows 环境中使用 C/C++ 联网

c++ - 在 C++ 中将有符号整数值转换为可排序、无符号的标准兼容方法是什么?

c# - 在 64 位下执行缓慢。可能是 RyuJIT 错误?