vb.net – UDP SocketException – 通常只允许使用每个套接字地
尽管这里有许多非常相似的问题,所提供的答案都没有帮助我,这让我很难过:(
我有一个非常大的管理系统,我一直负责编写一些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) 现在工作,所以我很高兴. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |