簡體   English   中英

退出在C#中讀取TCP的線程阻塞

[英]Exiting a thread blocking on TCP read in C#

我的服務器/客戶端啟動了一個新線程“ readerThread()”,用於讀取傳入的TCP通信。 該線程在read()上阻塞。 我如何才能退出此readerThread()。

一種方法是啟動另一個線程,該線程將在退出線程時關閉套接字,從而退出讀取。 有沒有更清潔/更好的方法來做到這一點。

我誤解了這個問題。 我認為這是您應該做的。

  • 如果您在父線程中創建了套接字 ,並且僅使用新線程來讀取傳入的數據,那么我建議您調用Socket.Shutdown()。這樣Receive方法將返回0(不讀取任何字節),並且可以從線程的方法。 關機將禁用發送/接收,但是如果緩沖區中有等待發送/接收的數據,它將確保在關閉套接字之前已發送/接收數據。 如果套接字在Receive上被阻止時調用shutdown,則Receive方法將返回0,但是它將引發套接字異常,且套接字錯誤代碼= Shutdown(或10058)。 因此,准備好抓住並處理它。

  • 如果在新線程及其接受的新連接(Socket.Listen()和Socket.Accept)中創建套接字,則可以從父線程與該套接字連接並發送0個字節。 當Receive方法返回0個字節時,您可以退出新線程。

  • 如果要在新線程中創建套接字,並且該套接字只能有一個客戶端(與其他套接字連接),那么這根本不是一個好方法。 除非您將服務器配置為在希望關閉客戶端套接字時發送0字節,否則您可能必須中止線程(不推薦),但是這樣,客戶端應用程序將依賴於服務器來關閉套接字。

如果使用阻塞的read()命令,則幾乎應該總是有另一個控制線程負責關閉它並清理套接字。

不過,通常,我會使用select()調用,該調用在1秒鍾左右后超時以測試是否有要讀取的數據,並且每個超時周期都會檢查另一個線程是否設置了關閉狀態標志。

但是,如果您使用純阻塞,請按照您的建議使用控制線程。

我會使用異步插座通訊。 我寫了一篇文章,在我的博客上對此進行了演示。 您可以在這里閱讀:

http://www.andrewrea.co.uk/blog/2009/06/09/Part1SocketProgrammingWithCJAVACAndActionScript30EstablishingABaseConnectionAndCommunicationWithCServerAndAS3.aspx

安德魯

我有點困惑您到底在做什么:.NET中的Socket類沒有read()方法。

我的建議是創建第二個套接字,該套接字在特定端口上偵聽,並將線程塊放入Socket.Select中 連接到第二個套接字應作為關閉請求(也許經過正確的身份驗證之后,例如,通過該套接字發送應用程序密碼)。

另一種方法是在要關閉它時,從您自己的應用程序中的其他位置向偵聽套接字發送一個0字節的數據包。

我發現這是一種比從另一個線程關閉coket的方法更干凈的方法,因為如果關閉套接字,偵聽線程將拋出異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM