Java 数据报套接字未接收数据包

发布于 2024-10-05 08:33:19 字数 2518 浏览 0 评论 0原文

我正在尝试使用 Java 数据报在服务器和客户端之间创建数据包流。问题是,尽管我收到了数据包正在发送的确认,但它们在到达我设置的客户端侦听器之前就全部丢失了。我现在有它,所以 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。另外,这个类并不是为了真正做任何重要的事情而设计的。因此,很多代码(例如异常处理)都是非常简单地编写的。

我可以做些什么来防止数据包丢失吗?我在我的计算机上转发了端口(这并不重要,我正在使用我的本地主机,如果您想知道的话,它是 App.Local)。

另外,附带问题。我最初将它设置为一个类,编码为发送一个数据包,然后转身接收一个数据包。但它抛出异常,因为“ICMP 端口无法访问”。有谁知道为什么会发生这种情况?

I'm attempting to use Java Datagrams to create a packet stream between server and client. The problem is that, although I receive confirmation that packets are being sent, they are all lost before they reach the client listener I set up. I have it right now so that there's a timeout after 5 seconds, which happens every time I run it.

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();
    }

}

You may choose to skim over the second class. They're widely the same, it just replaces server.send, with client.receive. Also, this class was not designed to really do anything important. So, a lot of the code(like, Exception handling), is written very simplistically.

Is there anything I can do to prevent the loss of packets? I have the port forwarded on my computer(not that it should matter, I'm using my localhost, which is App.Local in case you wondered).

Also, side question. I originally had it set up as a single class, coded to send a packet, then turn around and receive one. But it threw an exception because the 'ICMP Port is unreachable'. Does anyone know why this happens?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

旧人九事 2024-10-12 08:33:19

好吧,首先,我认为您正在同时测试服务器和客户端,因此您不知道哪一个失败了。

您应该使用netcat(nc)或wireshark来使用netcat测试客户端

,您可以运行以下命令

nc -l -u -p 4200 -vv

这将告诉netcat在端口(-p 4200)上的udp(-u)上侦听(-l)并且非常详细(-vv)

这样您就可以检查您的客户端是否可以连接到任何东西。

您可以使用相同的程序来检查您的服务器是否可以接收来自已知工作程序的连接

nc -u [target ip] 4200

这里有一个 netcat 备忘单

您还可以检查 netcat 到 netcat 来诊断是否纯粹是网络问题。可能防火墙/NAT 配置不正确

Ok first off, I think you are testing both the server and the client at the same time, so you don't have any idea whether which one fails.

You should use either netcat (nc) or wireshark to test the client

with netcat, you can run the following command

nc -l -u -p 4200 -vv

This will tell netcat to listen (-l) on udp (-u) on port (-p 4200) and be very verbose (-vv)

This way you'll be able to check if your client can connect to anything.

You can use the same program to check if your server can receive connections from a known working program with

nc -u [target ip] 4200

There is a netcat cheatsheet here

You can also check netcat to netcat to diagnose if it is purely a network issue. Maybe the firewalls/NAT aren't configured correctly

傾城如夢未必闌珊 2024-10-12 08:33:19

为什么服务器和客户端都进行连接?
一侧不应该发送数据吗?

像这样的东西:


DatagramSocket socket = new DatagramSocket();

DatagramPacket packet = new DatagramPacket(buf, buf.length, 
                                           address, 4200);
socket.send(packet);

Why both server and client doing a connect ?
Shouldn't one side be sending the data ?

Something like :


DatagramSocket socket = new DatagramSocket();

DatagramPacket packet = new DatagramPacket(buf, buf.length, 
                                           address, 4200);
socket.send(packet);

街道布景 2024-10-12 08:33:19

在我看来,有一些数据包过滤器/防火墙干扰您正在使用的端口上的客户端和服务器之间的 UDP 流量。它可能是简单的数据包过滤,也可能是 NAT(除非您采取特殊步骤,否则会干扰 UDP 流量),也可能是一些意外的网络配置错误。

但它抛出异常,因为“ICMP 端口无法访问”。有谁知道为什么会发生这种情况?

IMO,这是数据包过滤的更多证据。

(但是,您应该在尝试发送数据报时收到此响应,这也有点出乎您的意料。我只是希望根本没有响应,并且对 UDP 请求的任何 ICMP 响应都会被丢弃在地板上但是,我对此可能是错的......

现在如果您使用常规流套接字;例如 TCP/IP,这种行为是可以理解的。)

It sounds to me like there is some packet filter / firewall interfering with UDP traffic between the client and server on the port that you are using. It could be simple packet filtering, it could be NAT (which interferes with UDP traffic unless you take special steps), it could be some accidental network misconfiguration.

But it threw an exception because the 'ICMP Port is unreachable'. Does anyone know why this happens?

IMO, this is more evidence of packet filtering.

(However, its also a bit unexpected that you should receive this in response to trying to sent a datagram. I'd simply expect there to be no response at all, and any ICMP responses to a UDP request to have been dropped on the floor by the OS. But, I may be wrong about this ...

Now if you were using a regular stream socket; e.g. TCP/IP, this behaviour would be understandable.)

不必了 2024-10-12 08:33:19

您没有将发送套接字绑定到特定端口号,因此客户端在连接时将无法向其发送数据。我怀疑你也有同样的问题,即客户端套接字没有绑定到端口 4200。这可以解释一切。

我会在发送时摆脱连接并使用显式端口号,在回复时使用传入端口号。

You're not binding the sending socket to a specific port number, so the client won't be able to send to it if connected. I suspect you have the same problem in reverse as well, i.e. the client socket isn't bound to port 4200. That would explain everything.

I would get rid of the connects and use explicit port numbers when sending, and the incoming port number when replying.

情话墙 2024-10-12 08:33:19

我确信您知道 UDP 是一种有损协议并且您已经允许了这一点。不过你应该会收到一些数据包。

我建议您通过在同一主机和不同主机上使用客户端和服务器来测试您的程序是否工作,避开任何防火墙。如果这有效,那么您遇到了网络配置问题。

I am sure you are aware that UDP is a lossy proocol and you have allowed for this. Still you should expect to get some packets.

I suggest you test whether your program works by using the client and server on the same host and on different hosts, avoiding any firewalls. If this works then you have a network configuration issue.

天煞孤星 2024-10-12 08:33:19

如果您在同一台计算机上运行它们,则这永远不会起作用,因为您将两者(服务器和客户端)连接到同一端口。

If you are running both of them in the same machine this is never going to work because you are connecting both (server and client) to the same port.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文