gpt4 book ai didi

c# - 同一进程中两个套接字之间的 UDP 多播

转载 作者:太空狗 更新时间:2023-10-29 23:09:28 24 4
gpt4 key购买 nike

我正在为处理 UDP 多播通信的类编写一些测试。我将测试设计为使用环回接口(interface) (127.0.0.1) 进行测试,因为我不希望它们干扰网络上的其他程序/设备。

在我的“单元测试”中,我有一个经过测试的套接字,它加入给定的多播组并绑定(bind)到 127.0.0.1 和一个发件人套接字也加入了同一个多播组并绑定(bind)到 127.0.0.1,当然两者都在同一个进程中。

为了确保消息已发送,我有另一个测试程序(所以是另一个进程),它也加入多播组并输出发送给它的所有内容。

问题是我的测试套接字从未收到发送方发送的内容,但测试程序(因此另一个进程)收到了它。

多套接字/多播/本地主机的组合是否有一些限制?

新信息:

我的错误是认为本地主机上的 UDP 可能是可靠的。下面的测试程序显示我的监听套接字从未收到第一个 UDP 数据包(至少在我的计算机上)(但另一个进程仍然收到它)。

在我的单元测试中,我发送了一个数据包并期待特定的答案:我无法承受两次发送消息而只收到一次答案。

如果我在发送第一个数据包之前等待第一次接收超时发生,它似乎可以可靠地工作。

有谁知道为什么第一个 UDP 数据包永远不会到达?

这是我在试验中使用的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using NUnit.Framework;

namespace MulticastTest
{
[TestFixture]
public class Program
{
static void Main(string[] args)
{
new Program().Run();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}

[Test]
public void Run()
{
_waitFirstReadTiemout = new AutoResetEvent(false);
IPAddress lMulticastAddress = new IPAddress(0xFAFFFFEF);
IPEndPoint lRemoteEndPoint = new IPEndPoint(lMulticastAddress, 1900);

// Create sender socket
Socket lSendSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);

// Allow to share the port 1900 with other applications
lSendSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress,
true);

// Set TTL for multicast packets: socket needs to be bounded to do this
lSendSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.MulticastTimeToLive,
2);

// Bind the socket to the local end point: this MUST be done before joining the multicast group
lSendSocket.Bind(new IPEndPoint(IPAddress.Loopback, 55236));

// Join the multicast group
lSendSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.MulticastLoopback,
true);

lSendSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.AddMembership,
new MulticastOption(lMulticastAddress));

// Create receiver and start its thread
Thread lReceiveThread = new Thread(ReceiveThread);
lReceiveThread.Start();

int i = 0;
while (!fStop)
{
if (i == 0)
_waitFirstReadTiemout.WaitOne(10000);

byte[] lToSend = Encoding.ASCII.GetBytes(DateTime.Now.ToString("yyyyMMdd HHmmss"));
lSendSocket.SendTo(lToSend, lRemoteEndPoint);
Console.WriteLine("Sent #" + (i + 1) + ": " + DateTime.Now.ToString("yyyyMMdd HHmmss"));
Thread.Sleep(1000);
try
{
if (Console.KeyAvailable || i >= 10)
fStop = true;
}
catch (InvalidOperationException)
{
fStop = i >= 10;
}
finally
{
++i;
}
}
}

private AutoResetEvent _waitFirstReadTiemout;

private bool fStop;

private void ReceiveThread()
{
Socket lSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);

// Allow to share the port 1900 with other applications
lSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress,
true);

// TTL not required here: we will only LISTEN on the multicast socket
// Bind the socket to the local end point: this MUST be done before joining the multicast group
lSocket.Bind(new IPEndPoint(IPAddress.Loopback, 1900));

// Join the multicast group

// If the local IP is a loopback one, enable multicast loopback
lSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.MulticastLoopback,
true);

lSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.AddMembership,
new MulticastOption(
new IPAddress(0xFAFFFFEF)));

lSocket.ReceiveTimeout = 1000;

byte[] lBuffer = new byte[65000];
int i = 0;
while (!fStop)
{
try
{
int lReceived = lSocket.Receive(lBuffer);
++i;
Console.WriteLine("Received #" + i + ": " + Encoding.ASCII.GetString(lBuffer, 0, lReceived));
}
catch (SocketException se)
{
_waitFirstReadTiemout.Set();
Console.WriteLine(se.ToString());
}
}
}
}

最佳答案

这很可能是您的发送线程和接收线程之间的竞争——您在接收方加入组之前发送了第一个数据包。这解释了为什么它与超时一起工作。

关于c# - 同一进程中两个套接字之间的 UDP 多播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11793598/

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