【发布时间】:2016-01-11 19:09:44
【问题描述】:
大家好。
我的软件使用多播组发送消息,但是应用程序充当客户端和服务器,因此它发送 udp 数据包并接收它们。
这是使用包含 2000 个字符的文本进行测试的。
我创建了一个包含 byte[1024] 数组的队列,其中包含需要发送的数据。
问题:
问题在于接收这些多播数据包,在发送的 5 个数据包中,我大多只收到 1 个,经常收到 2 个等等,而且我收到了所有这些数据包的次数很少。
收发结果如下:
- 已发送数据包:已发送 1、2、3、4、5 个
- 返回的数据包:1、2、3、4、F(F是序列中的最后一个数据包,即关闭数据包)
12345 134F
12345 1F
12345 134F
12345 14F
12345 1F
12345 1F
12345 1
12345 1
12345 1
12345 1234F
12345 1F
12345 1
12345 1
12345 1
12345 14F
12345 1F
12345 1F
12345 1
12345 1
12345 1
12345 1F
12345 1
发送组播包如下:
Socket _listener_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
foreach (IPAddress localIP in Dns.GetHostAddresses(Dns.GetHostName()).Where(i => i.AddressFamily == AddressFamily.InterNetwork))
{
//handle image and files
_listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(_MultiIP, localIP));
_listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 1);
_listener_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_listener_socket.MulticastLoopback = true;
_listener_socket.Connect(new IPEndPoint(_MultiIP, _PORT));
while (count > 0)
{
count--;
byte[] temp = (byte[])(MSGS_TO_SEND.Dequeue());
_listener_socket.Send(temp, _BYTE_BUFFER_SIZE, SocketFlags.None);
MSGS_TO_SEND.Enqueue(temp);
}
}
_listener_socket.Close();
一个线程用于接收数据包并将它们添加到队列中进行处理,第二个线程用于处理。 2个线程的原因可能是接收线程中的处理过多导致了这个“丢包”,但不幸的是它没有解决问题
接收线程:
//initialise multicast group and bind to interface
Socket _sender_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, _PORT);
_sender_socket.Bind(ipep);
IPAddress localip = _MultiIP;
_sender_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(localip, IPAddress.Any));
Q_RECIEVE = new Queue<char[]>();
while (_sender_socket.IsBound && !bStop)
{
byte[] b = new byte[_BYTE_BUFFER_SIZE];
_sender_socket.Receive(b);
char[] chars = new char[_BYTE_BUFFER_SIZE];
System.Buffer.BlockCopy(b, 0, chars, 0, b.Length);
Q_RECIEVE.Enqueue(chars);
}
【问题讨论】:
-
UDP 是一种尽力而为的协议,没有任何方法可以确保接收到所有段。您应该期望不会收到所有发送的 UDP 段,这在设计时是预先知道的。如果您需要可靠性,请使用 TCP,但您不能使用 TCP 进行多播,因为多播是单向的,而 TCP 需要双向。
-
@RonMaupin 感谢您的回复,您有什么建议可以让我的软件获得最佳性能、减小数据包大小、“双”发送数据包?
标签: c# sockets networking network-programming