2016-12-13 181 views
-1

它不是真的重複。當使用非阻塞套接字時,你必須使用select方法來檢查連接是否被創建,在select方法中你可以設置一個超時值來終止。比方說,如果我想在預設的超時值之前中斷選擇方法,那又是同樣的問題。在我的情況下,選擇超時時間最長可達5分鐘,以防打印機忙於做某些事情而沒有時間回覆。break tcpip連接方法

從另一個線程關閉套接字取消連接,或選擇,似乎是我的問題的最佳解決方案。

我有程序連接到遠程TCPIP端口,它是一臺打印機。

SOCKET socket = socket(AF_INET, SOCK_STREAM, 0); 
struct sockaddr_in SockAddr; 
//... initialized host and port and so on 
int iret = connect(socket, &SockAddr, sizeof(SockAddr)); 
if (iret != 0) 
{ 
    // get error code... 
} 

只要打印機打開,它工作正常。如果打印機關閉,連接將失敗,並且「主機不可達」,這也很好。

如果打印機處於關閉狀態,連接方法將被阻止約20到21秒,然後返回失敗。這20秒應該從一些系統配置中計算出來,這很可能但很難改變。在其他系統上,這可能會更長。

我的問題是,是否有可能從連接方法,通過從另一個線程的另一個調用中斷?如果我發現打印機未打開,我想取消連接,不要停止應用程序,而是繼續執行一些日誌記錄作業。

如果我在進程中附加調試,暫停然後繼續,它似乎會提前中斷。

我不能在這裏使用非塊套接字,因爲它是一個非常大的項目,其他一切都是由其他人設計的塊套接字。我不允許做大的改變。

+0

什麼是「tcpip端口」?有TCP和IP。兩者都是不同的網絡層。 – Olaf

+0

@Olaf過於迂腐 - 將兩者結合在一起稱爲TCPIP – Alnitak

+1

@Alnitak:「數以百萬計的蒼蠅不會錯:吃sh **」:-)認真地說:僅僅因爲使用錯了並不意味着它應該是。混淆網絡層是導致錯誤觀念和問題的常見原因。 (它會過於迂腐,但要問什麼「tcpip」,因爲它通常被稱爲「TCP/IP」)。 – Olaf

回答

1

解除阻塞連接的最簡單方法是關閉套接字。不幸的是,在等待連接時,你的thead被掛起,所以你將不得不關閉另一個線程的套接字。

替代解決方案將使用異步io Windows與OVERLAPPED io做到這一點。在Linux上,可以將套接字設置爲非阻塞。這將導致connect在連接發生在後臺時立即返回。然後可以使用select或poll來等待套接字準備就緒。如果你添加標準輸入到選擇,按鍵會中斷選擇ABD可以根據需要進行處理。

+0

我正在嘗試此操作,但它需要一段時間。套接字被打開並存儲在一個結構中,我必須讓主線程訪問套接字。 –

+0

最簡單的方法是最好的。我只是從主線程調用closesocket,然後從阻塞的連接方法中斷開。 17:00:08.371連接到172.20.17.26:5001 17:00:08.549立即取消 17:00 00:08.549連接失敗10038 –