java一个进程多个套接字,UDP在同一进程中的两个套接字之间进行多播

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

在我的“单元测试”中,我有一个测试套接字,它连接到一个给定的多播组并绑定到127.0.0.1和一个发送器套接字,它也加入了同一个多播组并绑定到127.0.0.1,当然这两个进程都在同一个进程中 .

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

问题是我测试的套接字永远不会收到发送方发送的内容但是测试程序(因此另一个进程)接收它 .

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

新的消息:

我的错误是认为localhost上的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());

}

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值