gpt4 book ai didi

vb.net - UDP SocketException - 每个套接字地址通常只允许使用一次

转载 作者:行者123 更新时间:2023-12-04 16:34:45 28 4
gpt4 key购买 nike

尽管这里有很多非常相似的问题,但提供的答案都没有帮助我,这让我很难过:(

我有一个非常大的管理系统,我的任务是编写一些 UDP 数据包发送/接收。我已经编写了一个原型(prototype)并且一切都很好,所以我开始将我的代码合并到所述系统中。但是,我现在弹出了一个(不是停止显示,而是烦人的)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:\WORK\Trunk\GooseOrders\Classes\SheetCounter\DeviceServerUDPReceiver.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() .但是,当有人想再次启动它时, byData = _ReceivingClient.Receive(epEndPoint) 上会出现所述异常。 SitAndReceive 中的行程序。

由于 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)

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

关于vb.net - UDP SocketException - 每个套接字地址通常只允许使用一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17782957/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com