Я хочу написать некоторый код VB.NET, который отправляет несколько байтов в Broadcast и получает ответ от различных устройств, которые неизвестны при отправке: известно только номер порта для отправки широковещания, порт, который прослушивают эти устройства.
Единственный способ, которым я могу сделать эту работу на данный момент, - это синхронный способ (точнее, с асинхронными вызовами методов и синхронным ожиданием ответа, поэтому это синхронный путь), и это проблема, потому что мое приложениепри этом блокируется.
Вот код, который действительно работает:
broadcastIPEP = New IPEndPoint(IPBroadcast_, port_)
'Create Broadcaster
UDPClient = New UdpClient With {.EnableBroadcast = True}
'Send array of bytes
nbBytesSent = UDPClient.Send(bytTab, bytTab.Length, broadcastIPEP.Address.ToString, broadcastIPEP.Port)
'Get the number of the port to listen
port = DirectCast(UDPClient.Client.LocalEndPoint, IPEndPoint).Port
'Close broadcaster
UDPClient.Close()
'Create new listener on port
UDPClient = New UdpClient(port)
While True
nbMsWait = 0I
'Start receive
ar = UDPClient.BeginReceive(Nothing, Nothing)
'Wait answer until it comes
Do
nbMsWait += DELAY_WAIT_RESPONSE
If nbMsWait > DELAY_MAX_WAIT_RESPONSE Then
Exit Try
End If
ar.AsyncWaitHandle.WaitOne(DELAY_WAIT_RESPONSE)
Loop Until ar.IsCompleted
'Read answer
bytTab = UDPClient.EndReceive(ar, ipRemote)
strMsg = Text.Encoding.UTF8.GetString(bytTab)
'Process received message
ProcessResponse(strMsg)
End While
Он работает нормально, но, как я уже сказал, проблема в том, что он действительно не асинхронный.Все мои попытки заставить его работать асинхронным способом не работают, потому что данные никогда не поступают в мой UDPClient, когда я делаю это асинхронно.И я пробовал много способов: используя асинхронные методы чисто асинхронным способом, что-то вроде этого:
broadcaster = New UdpClient With {.EnableBroadcast = True}
broadcaster.BeginSend(BYTES_TO_SEND, NB_BYTES_TO_SEND, broadcastIPEP, New AsyncCallback(AddressOf OnDataSent), broadcaster)
Вот обратный вызов отправки
Protected Sub OnDataSent(ar As IAsyncResult)
'Local variables
Dim broadcaster As UdpClient = Nothing, client As UdpClient = Nothing
Dim port As Integer = 0I
Try
broadcaster = DirectCast(ar.AsyncState, UdpClient)
port = DirectCast(broadcaster.Client.LocalEndPoint, IPEndPoint).Port
broadcaster.Close()
client = New UdpClient(port)
'Schedule the next receive operation once reading is done:
client.BeginReceive(New AsyncCallback(AddressOf OnDataReceived), client)
Catch ex As Exception
ProcessError(ex)
End Try
End Sub
А вот обратный вызов приема:
Protected Sub OnDataReceived(ar As IAsyncResult)
'Local variables
Dim client As UdpClient = Nothing
Dim source As IPEndPoint = Nothing
Dim bytTab() As Byte = Nothing
Dim strMsg As String = String.Empty
Try
'This is what had been passed into BeginReceive as the second parameter:
client = DirectCast(ar.AsyncState, UdpClient)
'Points towards whoever had sent the message:
source = New IPEndPoint(0, 0)
'Get the actual message and fill out the source:
bytTab = client.EndReceive(ar, source)
'Process received message
strMsg = Encoding.GetString(bytTab)
ProcessResponse(strMsg)
'Schedule the next receive operation once reading is done:
client.BeginReceive(New AsyncCallback(AddressOf OnDataReceived), client)
Catch ex As Exception
ProcessError(ex)
End Try
End Sub
Выполнение входит в отправку обратного вызова, но никогда в обратный вызов приема.
Я пытался использовать синхронный метод в отдельном потоке, но та же проблема: невозможно получить что-либо, иЯ уверен, что есть что получить.Вот код подпрограммы потока:
'Local Variables
Dim nbBytes As Integer = 0I
Dim bytTab() As Byte = Nothing
Dim strMsg As String = String.Empty
Try
'Get broadcast address
broadcastIPEP = DirectCast(IP_, IPEndPoint)
'Create broadcaster
UDPBroadcaster = New UdpClient With {.EnableBroadcast = True}
'Set broadcast address to broadcaster
UDPBroadcaster.Connect(broadcastIPEP)
'Send broadcast
nbBytes = UDPBroadcaster.Send(BYTES_TO_SEND, NB_BYTES_TO_SEND)
'Get the port to listen
listenPort = DirectCast(UDPBroadcaster.Client.LocalEndPoint, IPEndPoint).Port
'Close broadcaster
UDPBroadcaster.Close()
'Create listener
UDPListener = New UdpClient(listenPort)
'Create listening address
listenIPEP = New IPEndPoint(IPAddress.Any, listenPort)
'listening loop
While booListen
Thread.Sleep(10I)
If booNotify Then
Continue While
End If
bytTab = UDPListener.Receive(listenIPEP)
strMsg = Text.Encoding.UTF8.GetString(bytTab)
ProcessResponseAsync(strMsg)
End While
Catch ex As Exception
ProcessError(ex)
End Try
Может кто-нибудь сказать мне, почему невозможно получить асинхронный прием с UDPClient?Спасибо всем, кто поможет