[英]How to read with a TcpClient until the other side closes or we stop in .Net
我有一個偵聽器,該偵聽器返回一個TcpClient,該TcpClient必須讀取數據,直到另一端關閉或停止為止。
我創建了一個帶有兩個按鈕的簡單表單。 一個啟動一個連接,另一個停止它。
問題是當由於讀取超時而發生IOException時,套接字已關閉,我無法再次與其通信。 我無法重新建立連接,因為另一端是建立連接的連接。
只需執行代碼和telnet到端口502,等待一秒鍾,您將看到問題。
你會怎么做?
Public Class Form1
Private m_listener As Net.Sockets.TcpListener
Private m_client As Net.Sockets.TcpClient
Private m_stopping As Boolean
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim data As Byte()
Dim dataLength As Integer
ReDim data(512)
m_listener = New Net.Sockets.TcpListener(Net.IPAddress.Any, 502)
m_listener.Start()
m_client = m_listener.AcceptTcpClient()
m_client.GetStream().ReadTimeout = 1000
m_client.GetStream().WriteTimeout = 1000
While Not m_stopping
Try
dataLength = m_client.GetStream.Read(data, 0, data.Length)
If dataLength = 0 Then
MsgBox("Disconnected")
Else
MsgBox(dataLength.ToString() & " bytes received")
End If
Catch ex As Exception When TypeOf (ex) Is TimeoutException OrElse (Not ex.InnerException Is Nothing AndAlso TypeOf (ex.InnerException) Is Net.Sockets.SocketException AndAlso DirectCast(ex.InnerException, Net.Sockets.SocketException).ErrorCode = 10060)
''# Just retry
End Try
End While
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
m_stopping = True
End Sub
End Class
該問題與以下問題有關: 在.NET中已關閉另一端時,如何關閉TcpClient?
最終:真正的問題是,要知道客戶端何時關閉連接,我必須執行一次讀取並檢查返回值是否為0。如果讀取具有無限超時,則調用將被阻塞,直到等到我才能結束應用程序讀取返回一些信息,如果讀取具有有限的超時,則我可以有一個TimeoutException,然后套接字將關閉。 那么……當其他部分關閉時,我該如何知道呢? 我不敢相信如此“輕松”的事情是如此艱難。
我找到了解決方案。 必須要做的是將Read()的超時設置為無窮大,並且當您需要取消阻止該Read調用時,只需調用Close()即可,而Read()將會取消阻止。
與嘗試從流中Read
並捕獲TimeoutException
,您可以檢查Available
屬性來確定是否有要讀取的數據。 這樣, TimeoutException
就不會發生,並且您仍然可以重用TcpClient
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.