我有1个进程充当服务器(TcpListener)和一个或多个充当客户端的进程(TcpClient)。客户端每隔1-2秒向服务器发送一次Tcp请求,服务器将使用结果消息进行响应。
在正常情况下,服务器在关闭时将使用TcpListener.Stop,但有时服务器会崩溃(无论出于何种原因),然后就不会这样做。如果我然后尝试重新启动然后我收到以下错误:
“通常只允许使用每个套接字地址(协议/网络地址/端口)”
只有 才会出现此错误,当有客户端正在运行并继续尝试连接时,尽管TcpListener不再存在(崩溃)。
当我在重新启动服务器/ TcpListener之前首次手动关闭/终止所有客户端时,我不收到此错误。
我正在寻找一个处理此错误/问题的自动恢复程序。怎么办呢?
您将在下面找到服务器和客户端的代码示例。
BTW:虽然代码示例在VB.NET中,但我也可以处理C#代码。这就是我用VB和C#标记这个问题的原因。server / TcpListener的代码示例:
Public Shared Sub Thread_TcpListener_GUI()
While True
Dim tcpClient As TcpClient = Nothing
Dim tcpListener As TcpListener = Nothing
Try
tcpListener = New TcpListener(System.Net.IPAddress.Any, 4960)
tcpListener.ExclusiveAddressUse = False
Call tcpListener.Start()
While True
tcpClient = tcpListener.AcceptTcpClient
Dim tcpNetworkStream As NetworkStream = tcpClient.GetStream()
Dim strMessageReceived As String = ""
'Get received message
While tcpNetworkStream.DataAvailable
Dim byteReceived(tcpClient.ReceiveBufferSize) As Byte
tcpNetworkStream.Read(byteReceived, 0, CInt(tcpClient.ReceiveBufferSize))
strMessageReceived &= Encoding.UTF8.GetString(byteReceived).Trim(Convert.ToChar(0))
End While
'Send response message
If strMessageReceived <> "" Then
Dim strResponse As String = "Received!"
Dim byteResponse As Byte() = Encoding.UTF8.GetBytes(strResponse)
tcpNetworkStream.Write(byteResponse, 0, byteResponse.Length)
End If
End While
Catch ex As Exception
Call Console.WriteLine(ex.Message)
Finally
Try
If tcpClient IsNot Nothing Then
If tcpClient.Connected Then
tcpClient.Close()
End If
End If
Catch ex As Exception
End Try
Try
If tcpListener IsNot Nothing Then
tcpListener.Stop()
tcpListener = Nothing
End If
Catch ex As Exception
End Try
Thread.Sleep(1500)
End Try
End While
End Sub
代码示例客户端:
Public Shared Sub TcpClient_SendMessage(ByVal strMessage As String)
Dim tcpClient As System.Net.Sockets.TcpClient = Nothing
Dim strResponse As String = ""
While True
Try
tcpClient = New System.Net.Sockets.TcpClient()
tcpClient.ExclusiveAddressUse = False
tcpClient.Connect("localhost", 4960)
Dim tcpNetworkStream As NetworkStream = tcpClient.GetStream()
'Send message
Dim byteMessage As Byte() = Encoding.UTF8.GetBytes(strMessage)
tcpNetworkStream.Write(byteMessage, 0, byteMessage.Length)
'Get respronse message
strResponse = ""
While tcpNetworkStream.DataAvailable
Dim byteResponse(tcpClient.ReceiveBufferSize) As Byte
tcpNetworkStream.Read(byteResponse, 0, CInt(tcpClient.ReceiveBufferSize))
strResponse &= Encoding.UTF8.GetString(byteResponse).Trim(Convert.ToChar(0))
End While
'Do something with response here ....
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
Try
If tcpClient IsNot Nothing Then
If tcpClient.Connected Then
tcpClient.Close()
tcpClient = Nothing
End If
End If
Catch ex As Exception
End Try
End Try
End While
End Sub
答案 0 :(得分:-1)
线程是后台线程或前台线程。后台线程与前台线程相同,除了后台线程不会阻止进程终止。一旦属于进程的所有前台线程终止,公共语言运行库就结束该进程。任何剩余的后台线程都会停止并且不会完成。
这里的问题是即使应用程序崩溃,侦听器也会继续运行。这是因为它在前台线程上运行。因此,您需要将其设置为后台线程,以便它随应用程序停止。
Dim receiverThread As Thread
receiverThread = New Thread(AddressOf Thread_TcpListener_GUI)
receiverThread.IsBackground = True
receiverThread.Start()
尝试以这种方式启动你的线程。希望这会有所帮助。