繁体   English   中英

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

[英]How to control the connect timeout with the Winsock API?

我正在使用Winsock API编写程序,因为一个朋友想要一个简单的程序来检查Minecraft服务器是否正在运行。 如果它正在运行,它可以正常工作,但是,如果它不在运行,则程序将冻结直到我假设连接超时。 另一个问题是,如果我有类似以下内容(伪代码):

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

它似乎跳过了tryConnection()的权限,完全忽略了它上面的内容。 我注意到这是因为程序将冻结,但不会将标签更改为“正在连接”。

这是我的实际连接代码:

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()。

无论哪种方式,在进行连接时,都要在主线程中运行一个计时器。 如果连接成功,请停止计时器。 如果计时器过去,请断开套接字,这将导致连接异常中止。

也许您想在这里阅读:

为了确保所有数据在关闭之前在连接的套接字上发送和接收,应用程序应在调用closesocket之前使用shutdown关闭连接。 http://msdn.microsoft.com/en-us/library/ms740481%28v=VS.85%29.aspx

由于您处于阻止模式,因此仍然可能会有一些数据...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM