【发布时间】:2013-09-13 13:34:43
【问题描述】:
我有一个发送多播数据包的应用程序。
我使用 BlockingCollection 来存储我必须发送的消息,然后一个线程专门用于发送只是迭代这个集合并在其中发送消息。每个本地 IP 都有一个套接字,因为我需要在每个 IP 上发送它。
它通常工作得很好,但最近,我的线程有几次挂在 Socket.SendTo 调用上,导致我的应用程序不再响应任何外部调用。我的 BlockingCollection 越来越大,而且从未被处理过。
我找不到任何理由让这个 Socket.SendTo 调用阻塞我的调用。如果是 TCP 调用,我可以想象对方没有人,但在这里使用 UDP,我看不出任何可能的问题。
我的代码基本上是:
Debug.WriteLine("Sending message on local endpoint " + socket.Key + ", to " + remoteEndpoint);
int sendTo = socket.Value.SendTo(buffer, remoteEndpoint);
Debug.WriteLine("Successfully sent a packet with "+sendTo+" bytes");
在我的日志中我看到:
[...]
Sending message on local endpoint 10.10.23.56, to 224.0.0.253:5353
Successfully sent a packet with 778 bytes
Sending message on local endpoint 10.9.53.38, to 224.0.0.253:5353
Successfully sent a packet with 778 bytes
Sending message on local endpoint 127.0.0.1, to 224.0.0.253:5353
Successfully sent a packet with 778 bytes
Sending message on local endpoint 10.10.23.56, to 224.0.0.253:5353
Successfully sent a packet with 778 bytes
Sending message on local endpoint 10.9.53.38, to 224.0.0.253:5353
Successfully sent a packet with 778 bytes
Sending message on local endpoint 127.0.0.1, to 224.0.0.253:5353
Successfully sent a packet with 778 bytes
Sending message on local endpoint 10.10.23.56, to 224.0.0.253:5353
Successfully sent a packet with 778 bytes
Sending message on local endpoint 10.9.53.38, to 224.0.0.253:5353¨
我这样创建我的套接字:
Socket sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 255);
sendSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
sendSocket.MulticastLoopback = true;
sendSocket.Bind(new IPEndPoint(localAddress, m_port));
sendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,new MulticastOption(m_multicastAddress, localAddress));
我看到here 在我发送完所有消息之前一直处于阻止状态,但是出于什么原因我的消息可能会被这样阻止?但是在这里,我的电话在这里被阻止了几分钟。
然后该怎么办?有时间在我的数据包未发送时处理 Socket 并尝试再次创建它吗?
编辑:我尝试对异步发送/接收做同样的事情,但更糟糕的是:我仍然在 EndReceiveTo 上被阻止,但此外,它阻止我终止进程(访问被拒绝,我是管理员,有重启:/)
编辑 在 xaxxon 回答之后,我把它放在发送消息之前,看看我是否有无法写入或错误的套接字:
List<Socket> socketWrite = socketToUse.Select(s => s.Value).ToList();
List<Socket> socketError = socketToUse.Select(s => s.Value).ToList();
Socket.Select(null, socketWrite, socketError, 1000);
Console.WriteLine("Writeable sockets: " + String.Join(", ", socketWrite.Select(s => s.LocalEndPoint.ToString())));
Console.WriteLine("Sockets in errors: " + String.Join(", ", socketError.Select(s => s.LocalEndPoint.ToString())));
But before I enter I get stuck on my `SendTo` call,
Writeable sockets: 10.10.23.56:5353, 10.9.53.38:5353, 127.0.0.1:5353
Sockets in errors:
Sending message on local endpoint 10.10.23.56, to 224.0.0.253:5353
Successfully sent a packet with 93 bytes
Sending message on local endpoint 10.9.53.38, to 224.0.0.253:5353
Successfully sent a packet with 93 bytes
Sending message on local endpoint 127.0.0.1, to 224.0.0.253:5353
Successfully sent a packet with 93 bytes
Writeable sockets: 10.10.23.56:5353, 10.9.53.38:5353, 127.0.0.1:5353
Sockets in errors:
Sending message on local endpoint 10.10.23.56, to 224.0.0.253:5353
Successfully sent a packet with 1162 bytes
Sending message on local endpoint 10.9.53.38, to 224.0.0.253:5353
__HERE I GET STUCK
【问题讨论】:
-
你正在做环回,但你没有阅读它。如果您不打算阅读,请不要设置环回。
-
但是,它是 UDP 多播,应该不需要阅读它们。另外我已经他们了(事实上,两次,服务器监听消息,客户端也是)。但这不是我当前的问题,因为我阻止了另一个 IP
-
如果您不想阅读它们,为什么要启用环回?这没有意义。请注意,这些是 cmets 而不是答案。
-
因为有时我需要拥有它们(比如在同一个工作站上拥有客户端和服务器时)。但同样,这不是我当前的问题
标签: c# .net sockets udp multicast