加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

vb.net – UDP SocketException – 通常只允许使用每个套接字地

发布时间:2020-12-17 00:08:29 所属栏目:大数据 来源:网络整理
导读:尽管这里有许多非常相似的问题,所提供的答案都没有帮助我,这让我很难过:( 我有一个非常大的管理系统,我一直负责编写一些UDP数据包发送/接收.我已经写了一个原型,一切都很好,所以我开始将我的代码合并到所述系统中.但是,我现在有一个(不显示停止但很恼人)Sock
尽管这里有许多非常相似的问题,所提供的答案都没有帮助我,这让我很难过:(

我有一个非常大的管理系统,我一直负责编写一些UDP数据包发送/接收.我已经写了一个原型,一切都很好,所以我开始将我的代码合并到所述系统中.但是,我现在有一个(不显示停止但很恼人)SocketException弹出:

System.Net.Sockets.SocketException occurred
  ErrorCode=10048
  Message=Only one usage of each socket address (protocol/network address/port) is normally permitted
  NativeErrorCode=10048
  Source=System
  StackTrace:
       at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot,SocketAddress socketAddress)
       at System.Net.Sockets.Socket.Bind(EndPoint localEP)
       at System.Net.Sockets.UdpClient..ctor(Int32 port,AddressFamily family)
       at System.Net.Sockets.UdpClient..ctor(Int32 port)
       at Goose.Job.DeviceServerUDPReceiver.InitialiseReceiverClient() in C:WORKTrunkGooSEOrdersClassesSheetCounterDeviceServerUDPReceiver.vb:line 39

这是UDPReceiver类 – 它负责只是坐在一个循环中,等待来自我们已经点缀该地方的设备服务器的响应.

Public Class DeviceServerUDPReceiver : Implements IDisposable
'///////////////////////////////////////////////////////////////////////////////
' CONSTANTS
'///////////////////////////////////////////////////////////////////////////////
Private Const TIBBO_DEVICE_REPLY_CMD_START As Integer = 0
Private Const TIBBO_DEVICE_REPLY_CMD_END As Integer = 3
Private Const TIBBO_MESSAGE_REPLY_DIVIDER As String = "_"
Private Const TIBBO_DEVICE_REPLY_OK As String = "OK"

'///////////////////////////////////////////////////////////////////////////////
' MEMBER VARIABLES
'///////////////////////////////////////////////////////////////////////////////
Public _ReceivingClient As System.Net.Sockets.UdpClient
Public _iReceivingPort As Integer = 2002
Public _thReceivingThread As System.Threading.Thread
Public _bClosing As Boolean

'///////////////////////////////////////////////////////////////////////////////
' EVENTS
'///////////////////////////////////////////////////////////////////////////////
Public Event GotDeviceResponse(ByVal sResponse As String)
Public Event FoundNewDevice(ByVal TibboObject As TibboDevice)

'///////////////////////////////////////////////////////////////////////////////
' METHODS
'///////////////////////////////////////////////////////////////////////////////
' Initialises the UDP receiver client on the specified port number. Then runs
' a listening thread constantly waiting to receive udp messages
Public Sub InitialiseReceiverClient()
    Try
        ' TODO - FIX SOCKET EXCEPTION HERE - NOT THREAD ISSUE - THIS IS DUE TO 
        ' THE SOCKET NOT BEING CLOSED. BUT SEEING HOW UDP IS CONNECTIONLESS .... ?!
        _ReceivingClient = New System.Net.Sockets.UdpClient(_iReceivingPort)
        Dim thStartThread As Threading.ThreadStart = New Threading.ThreadStart(AddressOf SitAndReceive)
        _thReceivingThread = New Threading.Thread(thStartThread)
        _thReceivingThread.IsBackground = True
        _thReceivingThread.Start()
    Catch ex As System.Net.Sockets.SocketException
        Console.WriteLine("Socket Exception: " & ex.Message)
    Finally

    End Try
End Sub

' The endless loop listener thread. Will sit and wait for udp packets to 
' process
Private Sub SitAndReceive()
    Dim epEndPoint As System.Net.IPEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Any,_iReceivingPort)

    ' infinite loop to listen for udp messages
    While (_bClosing = False)
        Try
            Dim sMessage As String = ""
            Dim byData() As Byte

            byData = _ReceivingClient.Receive(epEndPoint)
            sMessage = System.Text.Encoding.ASCII.GetString(byData)
            Console.WriteLine(sMessage)

            ProcessIncomingUDPDataMessage(sMessage)

        Catch ex As System.Net.Sockets.SocketException
            Console.WriteLine(ex.Message)
        End Try
    End While
End Sub

' close the connection to the receiving udp socket
Public Sub Close()
    _bClosing = True
End Sub


' Processes incoming udp packets for answeres from the device servers
Private Sub ProcessIncomingUDPDataMessage(ByVal sMessage As String)

    ' UDP Data packet from Tibbo devices is set out as follows
    '
    ' CMD_ANSWER
    ' Where "CMD" = The command the device is replying too and
    ' "ANSWER" = It's reply
    Select Case sMessage.Substring(TIBBO_DEVICE_REPLY_CMD_START,TIBBO_DEVICE_REPLY_CMD_END)
        Case TibboDevice.DEVICE_COMMAND_ATO
            '/////////////////////////////////////////////////////////////////////////
            ' Any Tibbo's out there reply message 
            '/////////////////////////////////////////////////////////////////////////
            Dim s() As String = sMessage.Split(TIBBO_MESSAGE_REPLY_DIVIDER)
            Dim sMacAddress As String = s(2) ' the replying devices' mac address
            Dim sIpAddress As System.Net.IPAddress = System.Net.IPAddress.Parse(s(3)) ' ip
            Dim sNetBiosName As String = s(1) ' netbios name
            Dim iTibboStatus As TibboDevice.ETIIBO_DEVICE_STATE = TibboDevice.ETIIBO_DEVICE_STATE.TIBBO_DEVICE_STATE_BAD ' status

            ' set this device status depending on the reply
            If s(4) = TIBBO_DEVICE_REPLY_OK Then
                iTibboStatus = TibboDevice.ETIIBO_DEVICE_STATE.TIBBO_DEVICE_STATE_OK
            End If

            ' create a new tibbo device to pass back to the main form
            Dim Tibbo As TibboDevice = New TibboDevice(sMacAddress,sIpAddress,sNetBiosName,iTibboStatus)
            ' raise event to add this to our list
            RaiseEvent FoundNewDevice(Tibbo)


        Case TibboDevice.DEVICE_COMMAND_STS
            '//////////////////////////////////////////////////////////////////////////
            ' Status reply message
            '//////////////////////////////////////////////////////////////////////////
            Dim s() As String = sMessage.Split(TIBBO_MESSAGE_REPLY_DIVIDER)
            Dim sResult As String = ""

            ' format our string nicely
            sResult &= "Mac Address: " & vbTab & vbTab & s(1)
            sResult &= Environment.NewLine & "IP Address: " & vbTab & vbTab & s(2)
            sResult &= Environment.NewLine & "Device Name: " & vbTab & vbTab & s(3)
            sResult &= Environment.NewLine & "TiOS FW: " & vbTab & vbTab & s(4)
            sResult &= Environment.NewLine & "Goose SC FW: " & vbTab & vbTab & s(5)
            sResult &= Environment.NewLine & "System Uptime: " & vbTab & vbTab & s(6)
            sResult &= Environment.NewLine & "System Time: " & vbTab & vbTab & s(7)
            sResult &= Environment.NewLine & "System Status: " & vbTab & vbTab & s(8)

            RaiseEvent GotDeviceResponse(sResult)

        Case TibboDevice.DEVICE_COMMAND_ASC
            '////////////////////////////////////////////////////////////////////////////
            ' Average sheet count message
            '////////////////////////////////////////////////////////////////////////////
            Dim s() As String = sMessage.Split(TIBBO_MESSAGE_REPLY_DIVIDER)
            Dim sResult As String = ""

            RaiseEvent GotDeviceResponse(sResult)

        Case TibboDevice.DEVICE_COMMAND_NAM
            '////////////////////////////////////////////////////////////////////////////
            ' Changed device name reply message
            ' Device will reply NAM_[NEWNAME] - once it's set it's new name
            '////////////////////////////////////////////////////////////////////////////
            Dim s() As String = sMessage.Split(TIBBO_MESSAGE_REPLY_DIVIDER)
            Dim sResult As String = ""

            RaiseEvent GotDeviceResponse(sResult)

        Case TibboDevice.DEVICE_COMMAND_IDX
            '////////////////////////////////////////////////////////////////////////////
            ' Device responds with it's device id
            '////////////////////////////////////////////////////////////////////////////
            Dim s() As String = sMessage.Split(TIBBO_MESSAGE_REPLY_DIVIDER)
            Dim sResult As String = ""

            ' TODO - do something with the result

        Case TibboDevice.DEVICE_COMMAND_RBT
            '////////////////////////////////////////////////////////////////////////////
            ' Device is going down for a reboot - not much to do here,we have to wait
            '////////////////////////////////////////////////////////////////////////////

        Case TibboDevice.DEVICE_COMMAND_BUZ
            '////////////////////////////////////////////////////////////////////////////
            ' Device has played it's buzz sound - ignore
            '////////////////////////////////////////////////////////////////////////////

        Case TibboDevice.DEVICE_COMMAND_FSH
            '////////////////////////////////////////////////////////////////////////////
            ' Device flashed it's LEDs - ignore
            '////////////////////////////////////////////////////////////////////////////

        Case TibboDevice.DEVICE_COMMAND_AIP
            '////////////////////////////////////////////////////////////////////////////
            ' Device replies with it's actual ip address
            '////////////////////////////////////////////////////////////////////////////
            Dim s() As String = sMessage.Split(TIBBO_MESSAGE_REPLY_DIVIDER)
            Dim sResult As String = ""

            ' TODO - do something with the result

        Case TibboDevice.DEVICE_COMMAND_CBC
            '////////////////////////////////////////////////////////////////////////////
            ' Device replies with it's current box count
            '////////////////////////////////////////////////////////////////////////////
            Dim s() As String = sMessage.Split(TIBBO_MESSAGE_REPLY_DIVIDER)
            Dim sResult As String = ""

            ' TODO - do something with the result

        Case TibboDevice.DEVICE_COMMAND_STP
            '////////////////////////////////////////////////////////////////////////////
            ' Device has been stopped - won't reply. Only way to bring it back to life
            ' is to press the 'reset' button on the actual unit - ignore
            '////////////////////////////////////////////////////////////////////////////
    End Select

End Sub

Protected Overridable Overloads Sub Dispose(disposing As Boolean)
    If (disposing) Then
        ' free managed objects
        '_ReceivingClient = Nothing
        _bClosing = True
    End If
End Sub

Public Overloads Sub Dispose() Implements IDisposable.Dispose
    Dispose(True)
    GC.SuppressFinalize(Me)
End Sub


End Class

现在,我在主窗体中所做的就是:当我的监听器窗体关闭时 – 我想关闭监听器(显然)……为此,我正在使用Dispose().但是,当有人想要再次启动它时,SitAndReceive过程中的byData = _ReceivingClient.Receive(epEndPoint)行会发生异常.

由于UDP是基于事务的,并且它的套接字(理论上可能)不能处于CLOSE_WAIT状态,是什么阻止我关闭它然后立即重新启动监听器?

我必须承认我是UDP套接字的新手,但到目前为止,我发现它们很愉快,即使这个异常不会导致最终用户软件崩溃(使用简单的try / catch),它确实让我好奇,我想了解为什么会这样.

很感谢任何形式的帮助.

管理最终解决这个问题.显然,如果要与套接字建立多个连接,则必须手动配置它,如下所示:
Dim endPoint = New System.Net.IPEndPoint(0,_iReceivingPort)
_ReceivingClient = New System.Net.Sockets.UdpClient()
_ReceivingClient.ExclusiveAddressUse = False
_ReceivingClient.Client.SetSocketOption(Net.Sockets.SocketOptionLevel.Socket,Net.Sockets.SocketOptionName.ReuseAddress,True)
 _ReceivingClient.Client.Bind(endPoint)

现在工作,所以我很高兴.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读