簡體   English   中英

Java數據報套接字未接收數據包

[英]Java Datagram Sockets not receiving packets

我正在嘗試使用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();
    }

}

您可以選擇略過第二節課。 它們大致相同,只是將server.send替換為client.receive。 另外,此類並非旨在真正做任何重要的事情。 因此,很多代碼(例如異常處理)非常簡單地編寫。

我有什么辦法可以防止數據包丟失? 我已經在我的計算機上轉發了端口(沒關系,我使用的是我的本地主機,如果您想知道的話,它是App.Local)。

另外,旁邊的問題。 我最初將其設置為單個類,編碼為發送一個數據包,然后轉身接收一個數據包。 但這是一個例外,因為“ ICMP端口無法訪問”。 有誰知道為什么會這樣嗎?

好的,首先,我想您正在同時測試服務器和客戶端,因此您不知道哪個會失敗。

您應該使用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配置不正確

如果您在同一台計算機上同時運行它們,那么這將永遠無法工作,因為您將(服務器和客戶端)都連接到了同一端口。

為什么服務器和客戶端都進行連接? 一方不應該發送數據嗎?

就像是 :


DatagramSocket socket = new DatagramSocket();

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

在我看來,好像有一些數據包篩選器/防火牆正在干擾您使用的端口上的客戶端和服務器之間的UDP通信。 它可能是簡單的數據包篩選,可能是NAT(除非采取特殊措施,否則會干擾UDP流量),可能是偶然的網絡配置錯誤。

但這是一個例外,因為“ ICMP端口無法訪問”。 有誰知道為什么會這樣嗎?

IMO,這是數據包過濾的更多證據。

(但是,您應該收到此消息以響應發送數據報的請求也有點出乎意料。我只是希望根本沒有任何響應,並且對UDP請求的所有ICMP響應都已經被丟棄了。通過操作系統。但是,我對此可能是錯誤的...

現在,如果您使用的是常規流套接字; 例如TCP / IP,這種行為是可以理解的。)

您沒有將發送套接字綁定到特定的端口號,因此如果連接,客戶端將無法發送給它。 我懷疑您在反向方面也有同樣的問題,即客戶端套接字未綁定到端口4200。這將解釋所有問題。

我會擺脫連接,在發送時使用顯式端口號,在回復時使用傳入的端口號。

我確定您知道UDP是有損協議,並且您已經允許這樣做。 您仍然應該期望得到一些數據包。

我建議您通過在同一主機和不同主機上使用客戶端和服務器來測試程序是否正常運行,並避免使用任何防火牆。 如果這可行,則您存在網絡配置問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM