1

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

}

2 番目のクラスをスキップすることもできます。それらはほとんど同じで、server.send を client.receive に置き換えるだけです。また、このクラスは実際に重要なことを行うようには設計されていません。そのため、多くのコード (例外処理など) は非常に単純化して記述されています。

パケットの損失を防ぐためにできることはありますか? 私は自分のコンピューターでポートを転送しています(問題ではありません。あなたが疑問に思っている場合は、App.Localであるローカルホストを使用しています)。

あと、横質問。私はもともと、パケットを送信し、向きを変えてパケットを受信するようにコード化された単一のクラスとしてセットアップしていました。しかし、「ICMP ポートに到達できない」ため、例外がスローされました。なぜこれが起こるのか誰か知っていますか?

4

6 に答える 6

5

まず最初に、サーバーとクライアントの両方を同時にテストしていると思うので、どちらが失敗するかわかりません。

クライアントをテストするには、netcat (nc) または wireshark のいずれかを使用する必要があります。

netcat を使用すると、次のコマンドを実行できます

nc -l -u -p 4200 -vv

これにより、ポート (-p 4200) で udp (-u) をリッスン (-l) し、非常に冗長 (-vv) にするように netcat に指示します。

このようにして、クライアントが何かに接続できるかどうかを確認できます。

同じプログラムを使用して、サーバーが既知の動作中のプログラムからの接続を受信できるかどうかを確認できます

nc -u [target ip] 4200

ここにnetcatチートシートがあります

netcat から netcat をチェックして、純粋にネットワークの問題であるかどうかを診断することもできます。ファイアウォール/NAT が正しく構成されていない可能性があります

于 2010-12-03T01:28:25.130 に答える
1

送信ソケットを特定のポート番号にバインドしていないため、接続されている場合、クライアントはそれに送信できません。逆に同じ問題があると思われます。つまり、クライアント ソケットがポート 4200 にバインドされていません。これですべてが説明されます。

接続を取り除き、送信時に明示的なポート番号を使用し、返信時に受信ポート番号を使用します。

于 2010-12-03T06:26:33.127 に答える
1

サーバーとクライアントの両方が接続を行うのはなぜですか? 一方がデータを送信するべきではありませんか?

何かのようなもの :


DatagramSocket socket = new DatagramSocket();

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

于 2010-12-03T01:25:36.237 に答える
1

使用しているポート上のクライアントとサーバー間のUDPトラフィックに干渉するパケットフィルター/ファイアウォールがあるように思えます。単純なパケット フィルタリング、NAT (特別な手順を踏まない限り UDP トラフィックに干渉する)、偶発的なネットワークの構成ミスなどの可能性があります。

しかし、「ICMP ポートに到達できない」ため、例外がスローされました。なぜこれが起こるのか誰か知っていますか?

IMO、これはパケット フィルタリングの証拠です。

(ただし、データグラムを送信しようとしているときにこれを受信するのも少し予想外です。まったく応答がなく、UDP 要求に対する ICMP 応答がフロアにドロップされていることを単純に期待します。 OSによって.しかし、これについては間違っているかもしれません...

通常のストリーム ソケットを使用していた場合は、次のようになります。たとえば TCP/IP の場合、この動作は理解できます。)

于 2010-12-03T01:26:46.027 に答える
0

両方を同じマシンで実行している場合、両方(サーバーとクライアント)を同じポートに接続しているため、これは機能しません。

于 2012-05-08T22:15:36.817 に答える
0

UDP は損失の多いプロトコルであり、これを許可していることを認識していると思います。それでも、いくつかのパケットを取得することを期待する必要があります。

ファイアウォールを避けて、同じホストと異なるホストでクライアントとサーバーを使用して、プログラムが機能するかどうかをテストすることをお勧めします。これが機能する場合は、ネットワーク構成に問題があります。

于 2010-12-03T07:46:33.683 に答える