I'm trying to write a very simple UDP client/server pair that will work together on the same computer (for now), but none of my packets are being delivered. The code below is a 100% complete VB.NET console application. It runs without throwing errors, but the mListener.Receive command never returns.
我正在尝试编写一个非常简单的UDP客户机/服务器对,它们将在同一台计算机上一起工作(现在),但是我的包都没有被交付。下面的代码是100%完整的VB。净控制台应用程序。它运行时不会抛出错误,而是mListener。接收命令从来没有回报。
Question 1: Why am I not receiving any packets?
问题1:为什么我没有收到任何数据包?
Question 2: Why can't I have my Client use IPAddress.Any as an end point? When I try to connect to New IPEndPoint(IPAddress.Any, 10123), I get a "The requested address is not valid in its context 0.0.0.0:10123" exception.
问题2:为什么我不能让我的客户使用IPAddress。任何作为终点?当我尝试连接到新的IPEndPoint(IPAddress)时。任何,10123),我得到一个“被请求的地址在其上下文0.0.0.0:10123”异常中无效。
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Module Module1
Sub Main()
Dim ep As New IPEndPoint(IPAddress.Loopback, 10123)
Dim s As New Server(ep)
Dim c As New Client(ep)
Do
Console.WriteLine("Waiting in main loop...")
Thread.Sleep(5000)
Loop
End Sub
End Module
Public Class Server
Private mBroadcaster As UdpClient
Public Sub New(ep As IPEndPoint)
mBroadcaster = New UdpClient
mBroadcaster.ExclusiveAddressUse = False
mBroadcaster.Connect(ep)
Dim sender As New Thread(AddressOf SendLoop)
sender.Start()
End Sub
Private Sub SendLoop()
Do
Dim msg As Byte() = Text.ASCIIEncoding.ASCII.GetBytes("Hello world")
Console.WriteLine("Sending...")
mBroadcaster.Send(msg, msg.Length)
Thread.Sleep(1000)
Loop
End Sub
End Class
Public Class Client
Private mListener As UdpClient
Public Sub New(ep As IPEndPoint)
mListener = New UdpClient
mListener.ExclusiveAddressUse = False
mListener.Connect(ep) 'Why can't I use IPAddress.Any here?
Dim poller As New Thread(AddressOf PollLoop)
poller.Start()
End Sub
Private Sub PollLoop()
Do
Dim ep As IPEndPoint = Nothing
Console.WriteLine(" Receiver listening...")
Dim incomingbytes As Byte() = mListener.Receive(ep)
Dim msg As String = Text.ASCIIEncoding.ASCII.GetString(incomingbytes)
Console.WriteLine(" Received: " & msg & " from " & ep.Address.ToString & ":" & ep.Port)
Loop
End Sub
End Class
1 个解决方案
#1
0
I still don't know why the original code doesn't work, but I did find a way to accomplish what the original code intends. The basic idea is that it's apparently fine to use a UdpClient for the server, but it's not ok to use a UdpClient for...the client. Instead, I changed the UdpClient to a lower-level Socket. I suspect it would also be fine to replace the Server's UdpClient with a Socket as well, but I haven't tested that. This also resolves question 2 (the raw Socket allows for listening on IPAddress.Any).
我仍然不知道为什么原始代码不起作用,但是我确实找到了一种方法来实现原始代码的意图。基本的想法是,使用UdpClient作为服务器显然是可以的,但是使用UdpClient作为…是不合适的。客户端。相反,我将UdpClient改为一个较低级别的套接字。我怀疑用套接字替换服务器的UdpClient也很好,但是我还没有测试过。这也解决了问题2(原始的套接字允许监听IPAddress.Any)。
I would still accept a different answer that actually explains why this is the case.
我仍然会接受一个不同的答案来解释为什么会这样。
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Module Module1
Sub Main()
Dim s As New Server
Dim c As New Client
Do
Console.WriteLine("Waiting in main loop...")
Thread.Sleep(5000)
Loop
End Sub
End Module
Public Class Server
Private mBroadcaster As UdpClient
Public Sub New()
mBroadcaster = New UdpClient
mBroadcaster.ExclusiveAddressUse = False
mBroadcaster.Connect(New IPEndPoint(IPAddress.Broadcast, 10123))
Dim sender As New Thread(AddressOf SendLoop)
sender.Start()
End Sub
Private Sub SendLoop()
Do
Dim msg As Byte() = Text.ASCIIEncoding.ASCII.GetBytes("Hello world")
Console.WriteLine("Sending...")
mBroadcaster.Send(msg, msg.Length)
Thread.Sleep(1000)
Loop
End Sub
End Class
Public Class Client
Private mListener As Socket
Public Sub New()
mListener = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
mListener.ExclusiveAddressUse = False
mListener.Bind(New IPEndPoint(IPAddress.Any, 10123))
Dim poller As New Thread(AddressOf PollLoop)
poller.Start()
End Sub
Private Sub PollLoop()
Dim buffer As Byte() = New Byte(1023) {}
Do
Console.WriteLine(" Receiver listening...")
Dim nbytes As Integer = mListener.Receive(buffer)
Dim msg As String = Text.ASCIIEncoding.ASCII.GetString(buffer, 0, nbytes)
Console.WriteLine(" Received: " & msg)
Loop
End Sub
End Class
#1
0
I still don't know why the original code doesn't work, but I did find a way to accomplish what the original code intends. The basic idea is that it's apparently fine to use a UdpClient for the server, but it's not ok to use a UdpClient for...the client. Instead, I changed the UdpClient to a lower-level Socket. I suspect it would also be fine to replace the Server's UdpClient with a Socket as well, but I haven't tested that. This also resolves question 2 (the raw Socket allows for listening on IPAddress.Any).
我仍然不知道为什么原始代码不起作用,但是我确实找到了一种方法来实现原始代码的意图。基本的想法是,使用UdpClient作为服务器显然是可以的,但是使用UdpClient作为…是不合适的。客户端。相反,我将UdpClient改为一个较低级别的套接字。我怀疑用套接字替换服务器的UdpClient也很好,但是我还没有测试过。这也解决了问题2(原始的套接字允许监听IPAddress.Any)。
I would still accept a different answer that actually explains why this is the case.
我仍然会接受一个不同的答案来解释为什么会这样。
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Module Module1
Sub Main()
Dim s As New Server
Dim c As New Client
Do
Console.WriteLine("Waiting in main loop...")
Thread.Sleep(5000)
Loop
End Sub
End Module
Public Class Server
Private mBroadcaster As UdpClient
Public Sub New()
mBroadcaster = New UdpClient
mBroadcaster.ExclusiveAddressUse = False
mBroadcaster.Connect(New IPEndPoint(IPAddress.Broadcast, 10123))
Dim sender As New Thread(AddressOf SendLoop)
sender.Start()
End Sub
Private Sub SendLoop()
Do
Dim msg As Byte() = Text.ASCIIEncoding.ASCII.GetBytes("Hello world")
Console.WriteLine("Sending...")
mBroadcaster.Send(msg, msg.Length)
Thread.Sleep(1000)
Loop
End Sub
End Class
Public Class Client
Private mListener As Socket
Public Sub New()
mListener = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
mListener.ExclusiveAddressUse = False
mListener.Bind(New IPEndPoint(IPAddress.Any, 10123))
Dim poller As New Thread(AddressOf PollLoop)
poller.Start()
End Sub
Private Sub PollLoop()
Dim buffer As Byte() = New Byte(1023) {}
Do
Console.WriteLine(" Receiver listening...")
Dim nbytes As Integer = mListener.Receive(buffer)
Dim msg As String = Text.ASCIIEncoding.ASCII.GetString(buffer, 0, nbytes)
Console.WriteLine(" Received: " & msg)
Loop
End Sub
End Class