至於因爲有在這裏是非常相似的,沒有提供答案,幫助我,這讓我傷心:(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:\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()
。但是,當有人想再次啓動它時,在SitAndReceive
過程的byData = _ReceivingClient.Receive(epEndPoint)
行中發生異常。
由於UDP基於事務,並且其套接字(理論上可能不能處於CLOSE_WAIT狀態),什麼阻止我關閉它,然後立即重新啓動偵聽器?
我必須承認我是UDP套接字的新手,但迄今爲止,我發現他們很高興與之合作,即使此異常不會使最終用戶軟件崩潰(通過簡單的try/catch ),它確實讓我感興趣,我想了解它爲什麼會發生。
任何幫助,非常感謝。
不錯!我遇到了同樣的問題。我花了一段時間才弄清楚它爲什麼沒有工作,我意識到我正在用一個端口實例化我的UdpClient對象(比如'_receiver = new UdpClient(myPort)'),它必須做一些底層綁定。在我使用默認構造函數後,它工作正常。 – Daniel
不錯的一個:)很高興你的工作! – LokiSinclair
你的解決方案工作得很好!我正在發送多播請求,在同一主機上有多個接收器。當我試圖運行多個不得不聽同一端口的接收器時,我遇到了同樣的錯誤。 –