1

こんにちは、データグラムを使用してエコー クライアント - サーバー コードを作成しました。コードが実行され、クライアント側から送信されたメッセージがサーバー側で受信され、クライアントにエコー バックされます。次のシナリオは、私が抱えている問題を示しています

1-> クライアント: こんにちは、サーバー: こんにちは、エコー バック: こんにちは

2-> クライアント: hello 、サーバー: hello 、エコー バック: hello クライアントが最後のメッセージよりも短いメッセージを入力すると、次のことが起こります。

3->クライアント: K、サーバー: Kello、エコーバック: K

サーバーが前のメッセージの残りの文字を出力する理由がわかりません。サーバー側のコードは次のとおりです。

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;

    import javax.swing.SwingUtilities;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JScrollBar;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;

    public class Server extends JFrame {
int port;
// JTextField textField;
JButton resendPacket;
JTextArea chatWindow;
DatagramSocket socket;
private final int PACKET_SIZE = 124;
private final int port_Number = 6789;
DatagramPacket packet =  new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);

    InetAddress host;


public Server() {
    super("INSTANT ECHO - SERVER");
    resendPacket = new JButton("Echo");
    chatWindow = new JTextArea();

//  add(resendPacket, BorderLayout.SOUTH);
    add(new JScrollPane(chatWindow));
    setSize(300, 300);
    setVisible(true);
}

public void startRunning() {

    try {
        port = 6777;
        socket = new DatagramSocket(port);
        showMessage("Server is Ready... \n");
        /*resendPacket.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                try {
                    socket.send(packet);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }); */
        while(true)
        {
            processPacket();
        }


    } catch (SocketException e) {
        // TODO: handle exception
        showMessage("\n Could not send packet!\n");
        e.printStackTrace();
    } 
}

private void processPacket() {




    // create a packet

    // receive a packet

    try {
        socket.receive(packet);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        showMessage("\nCould not receive Packet");
        e.printStackTrace();
    }
    try {
        socket.send(packet);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    // display the contents of the packet
    showMessage(new String(packet.getData()));



    // send the packet again to the sender

}

public void showMessage(final String text) {
    SwingUtilities.invokeLater(

    new Runnable() {

        public void run() {
            chatWindow.append("\n Packet Data : " + text);
        }
    });

}

}

そして、これがクライアント側のコードです

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;

    public class Client extends JFrame {
int port = 6777;
JTextField textField;
String data = "hello" ;
// JButton sendPacket;
JTextArea chatWindow;
DatagramSocket socket;
DatagramPacket packet;
private final int PACKET_SIZE = 124;
InetAddress host;

public Client() {
    super("INSTANT ECHO - CLIENT");

    textField = new JTextField();
    try {
        host = InetAddress.getByName("127.0.0.1");
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        showMessage("\n Could not find local host");
        e.printStackTrace();
    }

試す {

        socket = new DatagramSocket();

    } catch (SocketException e) {
        // TODO Auto-generated catch block
        showMessage("\n Could not find Socket");
        e.printStackTrace();
    }
    // textField.setEditable(false);
    textField.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent event) {
            // TODO Auto-generated method stub
            data = event.getActionCommand();
            showMessage(event.getActionCommand());
            startRunning();
            textField.setText("");

        }
    });

    chatWindow = new JTextArea();
    add(textField, BorderLayout.SOUTH);


    add(new JScrollPane(chatWindow));
    setSize(300, 300);
    setVisible(true);

}

public void startRunning() {



    byte[] bytes_to_send = data.getBytes();

    DatagramPacket packet = new DatagramPacket(bytes_to_send,
            bytes_to_send.length, host, port);
    try {


        sendPacket(packet);
        setTime();
        receivePacket(packet);

        socket.receive(packet);
        showMessage("\n" + new String(packet.getData()));
    } catch (IOException e) {
        // TODO Auto-generated catch block

        e.printStackTrace();
    } finally {
        //closeCrap();
    }

}

private void sendPacket(DatagramPacket packet) {
    try {
        textField.setEditable(true);

        socket.send(packet);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        showMessage("\nUnable to send Packet !");
        e.printStackTrace();
    }
}

private void setTime() {
    try {
        socket.setSoTimeout(5);
    } catch (SocketException e) {
        // TODO Auto-generated catch block
        showMessage("\nRequest Time Out");
        e.printStackTrace();
    }
}

private void receivePacket(DatagramPacket packet) {
    packet = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);

    try {
        socket.receive(packet);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        showMessage("\n Unable to receive packet\n");
        e.printStackTrace();
    }
    showMessage("\n Echoed Message --> "+new String(packet.getData()));
}

private void closeCrap() {
    socket.close();
}

private void showMessage(final String data) {
    SwingUtilities.invokeLater(

    new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            chatWindow.append("\n" + data);

        }
    });

}

}

以前の文字が印刷されている理由を誰か教えてもらえますか?

4

2 に答える 2

2

DatagramPacket.getLength()には、使用されたバッファーの長さが含まれます。

試す

showMessage(new String(packet.getData(), 0, packet.getLength()));
于 2012-10-31T14:17:42.317 に答える
0

同じパケットを何度も再利用しているため、ネットワークから情報を読み取ると、既存のパケットバッファの内容が新しい内容で上書きされます。クライアントはnullターミネータを書き込んでいないため、バッファには何も書き込まれていません。showMessage(new String(packet.getData()));そのため、受け取ったばかりのメッセージが古い内容を完全に上書きするのに十分な長さでない場合、取得したデータを使用してデータを印刷すると、古いデータの残りが残ります。

packet.getLength()パケットを送信すると、送信されるバイト数を制御するソケットが従うため、余分なデータはエコーバックされません。

次のいずれかを実行できます。

  • showMessageの呼び出しを次のように変更します。

    showMessage("\n Echoed Message --> " + 
                new String(packet.getData(), 0, packet.getLength()));
    
  • 毎回異なるパケットを使用する

それらのいずれかがそれを修正する必要があります。

于 2012-10-31T14:21:23.437 に答える