如何修复错误“通常只允许使用每个套接字地址”

时间:2012-01-23 12:25:38

标签: c# vb.net tcp

我有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

1 个答案:

答案 0 :(得分:-1)

线程是后台线程或前台线程。后台线程与前台线程相同,除了后台线程不会阻止进程终止。一旦属于进程的所有前台线程终止,公共语言运行库就结束该进程。任何剩余的后台线程都会停止并且不会完成。

这里的问题是即使应用程序崩溃,侦听器也会继续运行。这是因为它在前台线程上运行。因此,您需要将其设置为后台线程,以便它随应用程序停止。

    Dim receiverThread As Thread

    receiverThread = New Thread(AddressOf Thread_TcpListener_GUI)
    receiverThread.IsBackground = True
    receiverThread.Start()

尝试以这种方式启动你的线程。希望这会有所帮助。