我写了两个小应用程序(一个客户端和一个服务器)来测试UDP通信,我发现它们之间的“连接”(是的,我知道,没有真正的连接)会无缘无故地丢失。
我知道UDP是一个不可靠的协议,但这里的问题似乎不是数据包的丢失,而是应用程序之间通信渠道的丢失。
这是客户端应用代码:
class ClientProgram
{
static void Main(string[] args)
{
var localEP = new IPEndPoint(GetIPAddress(), 0);
Socket sck = new UdpClient(localEP).Client;
sck.Connect(new IPEndPoint(IPAddress.Parse("[SERVER_IP_ADDRESS]"), 10005));
Console.WriteLine("Press any key to request a connection to the server.");
Console.ReadLine();
// This signals the server this clients wishes to receive data
SendData(sck);
while (true)
{
ReceiveData(sck);
}
}
private static void ReceiveData(Socket sck)
{
byte[] buff = new byte[8];
int cnt = sck.Receive(buff);
long ticks = BitConverter.ToInt64(buff, 0);
Console.WriteLine(cnt + " bytes received: " + new DateTime(ticks).TimeOfDay.ToString());
}
private static void SendData(Socket sck)
{
// Just some random data
sck.Send(new byte[] { 99, 99, 99, 99 });
}
private static IPAddress GetIPAddress()
{
IPHostEntry he = Dns.GetHostEntry(Dns.GetHostName());
if (he.AddressList.Length == 0)
return null;
return he.AddressList
.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !IPAddress.IsLoopback(ip))
.FirstOrDefault();
}
}
这是服务器应用代码:
class ServerProgram
{
private static int SLEEP = 5;
static void Main(string[] args)
{
// This is a static IP address
var localEP = new IPEndPoint(GetIPAddress(), 10005);
Socket sck = new UdpClient(localEP).Client;
// When this methods returs, a client is ready to receive data
var remoteEP = ReceiveData(sck);
sck.Connect(remoteEP);
while (true)
{
SendData(sck);
System.Threading.Thread.Sleep( ServerProgram.SLEEP * 1000);
}
}
private static EndPoint ReceiveData(Socket sck)
{
byte[] buff = new byte[8];
EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
int cnt = sck.ReceiveFrom(buff, ref clientEP);
Console.WriteLine(cnt + " bytes received from " + clientEP.ToString());
return (IPEndPoint)clientEP;
}
private static void SendData(Socket sck)
{
DateTime n = DateTime.Now;
byte[] b = BitConverter.GetBytes(n.Ticks);
Console.WriteLine("Sending " + b.Length + " bytes : " + n.TimeOfDay.ToString());
sck.Send(b);
}
private static IPAddress GetIPAddress()
{
// Same as client app...
}
}
(这只是测试代码,不注意无限循环或缺乏数据验证)
问题是在发送一些消息后,客户端停止接收它们。服务器继续发送,但客户端卡在sck.Receive(buff)
。如果我将SLEEP常量更改为大于5的值,则大多数情况下在3或4条消息之后“连接”会丢失。
我可以确认客户端计算机在连接丢失时没有收到任何数据包,因为我使用Wireshark来监控通信。
服务器应用程序在直接连接到Internet的服务器上运行,但客户端是路由器后面的本地网络中的计算机。他们都没有运行防火墙。
有没有人知道这里会发生什么?
谢谢!
编辑 - 其他数据:
我在同一网络中的多台计算机上测试了客户端应用程序,并且连接总是丢失。我还测试了其他路由器后面的其他网络中的客户端应用程序,那里没有问题。我的路由器是Linksys RV042,从来没有任何问题,事实上,这个应用程序是唯一有问题的。
答案 0 :(得分:1)
我没有在源代码中看到任何明显的问题。如果确实如此:
..然后问题可能与两台机器之间的网络设备有关,这两台机器并不总是按预期处理UDP流,特别是在路由器/防火墙后面。
我建议采用以下方法进行故障排除:
如果所有内容都是切换本地的,那么您可以确定您遇到了网络配置问题。