簡體   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