我正在尝试使用Java Datagrams在服务器和客户端之间创建数据包流。问题是,虽然我收到确认数据包正在发送,但它们在到达我设置的客户端监听器之前都已丢失。我现在就拥有它,以便在5秒后出现超时,每次运行都会发生。
class DGServer extends Thread
{
private DatagramSocket server;
public DGServer() throws IOException
{
server = new DatagramSocket();
}
public void run()
{
try
{
server.connect(App.Local, 4200);
System.out.println("Server starting...");
int i = 0;
while (server.isConnected() && (i < 256))
{
byte[] buffer = new byte[1];
buffer[0] = (byte) ++i;
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, App.Local, 4200);
System.out.println("Sedning " + i + " to client...");
server.send(packet);
Thread.sleep(500);
}
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("Server Finished!");
if (! server.isClosed())
server.close();
}
}
class DGClient extends Thread
{
private DatagramSocket client;
public DGClient() throws SocketException
{
client = new DatagramSocket();
}
public void run()
{
try
{
client.connect(App.Local, 4200);
client.setSoTimeout(5000);
System.out.println("Client starting...");
int i = 0;
while (client.isConnected() && (i < 256))
{
byte[] buffer = new byte[1];
DatagramPacket packet;
packet = new DatagramPacket(buffer, 1, App.Local, 4200);
//System.out.println("Sedning " + i + " to server...");
client.receive(packet);
buffer = packet.getData();
System.out.println("Client Received:\t" + packet.getData()[0]);
Thread.sleep(500);
}
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("Client Finished!");
if (! client.isClosed())
client.close();
}
}
您可以选择浏览第二堂课。它们大致相同,它只是用client.receive替换server.send。此外,这门课程并非旨在真正做任何重要的事情。因此,很多代码(例如,异常处理)的编写非常简单。
我能做些什么来防止丢包?我在我的计算机上转发了端口(不是它应该重要,我正在使用我的localhost,这是App.Local以防万一你想知道)。
另外,附带问题。我最初将它设置为单个类,编码发送数据包,然后转身接收一个。但它引发了一个例外,因为“ICMP端口无法访问”。有谁知道为什么会这样?
答案 0 :(得分:5)
好的,首先,我认为您同时测试服务器和客户端,因此您不知道哪一个发生故障。
您应该使用netcat(nc)或wireshark来测试客户端
使用netcat,您可以运行以下命令
nc -l -u -p 4200 -vv
这将告诉netcat在端口(-p 4200)上的udp(-u)上监听(-l)并且非常详细(-vv)
通过这种方式,您可以检查客户端是否可以连接任何内容。
您可以使用相同的程序检查您的服务器是否可以使用
从已知的工作程序接收连接nc -u [target ip] 4200
There is a netcat cheatsheet here
您还可以检查netcat到netcat以诊断它是否纯粹是网络问题。可能防火墙/ NAT未正确配置
答案 1 :(得分:1)
为什么服务器和客户端都在进行连接? 一方不应该发送数据吗?
类似的东西:
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(buf, buf.length,
address, 4200);
socket.send(packet);
答案 2 :(得分:1)
在我看来,有一些数据包过滤器/防火墙干扰了您正在使用的端口上的客户端和服务器之间的UDP流量。它可能是简单的数据包过滤,它可能是NAT(除非你采取特殊步骤干扰UDP流量),它可能是一些意外的网络配置错误。
但它引发了一个例外,因为“ICMP端口无法访问”。有谁知道为什么会这样?
IMO,这是包过滤的更多证据。
(但是,它也有点意外,你应该收到这个以响应尝试发送数据报。我只是希望根本没有响应,并且任何ICMP对UDP请求的响应都被删除操作系统在地板上。但是,我可能错了...
现在,如果您使用常规流套接字;例如TCP / IP,这种行为是可以理解的。)
答案 3 :(得分:1)
您没有将发送套接字绑定到特定端口号,因此如果连接,客户端将无法发送到该端口号。我怀疑你反向也有同样的问题,即客户端套接字没有绑定到端口4200.这可以解释一切。
我会在发送时删除连接并使用显式端口号,并在回复时使用传入端口号。
答案 4 :(得分:1)
如果您在同一台计算机上运行它们,那么这将无法正常工作,因为您将两者(服务器和客户端)连接到同一个端口。
答案 5 :(得分:0)
我确信你知道UDP是一个有损的协议,你已经允许这样做了。你还应该期待获得一些数据包。
我建议您使用同一主机和不同主机上的客户端和服务器测试您的程序是否正常工作,避免任何防火墙。如果这样可行则会出现网络配置问题。