Hi I made an echo client – server code using datagram. The code is running and the messages sent from the client side are being received at the server side, then they are echoed back to the client. The following scenario shows what problem I am having
1->Client: hi , server : hi ,
echoed back : hi
2->Client: hello , server : hello ,
echoed back : hello
Now when the client types a message shorter than the last one the following thing happens
3->Client: K , server : Kello ,
echoed back : K
I can’t understand why the server prints the rest of the characters of the previous message, here is the server side code:
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);
}
});
}
}
And here is the client side code
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();
}
try {
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);
}
});
}
}
Can anyone tell why the previous characters are getting printed?
You’re reusing the same packet over and over, so when it reads information from the network, it overwrites the existing packet buffer contents with new content. The client isn’t writing a null terminator, so none is being written into the buffer. As such, when you print the data with
showMessage(new String(packet.getData()));the data you get back still has remnants of the old data in it if the message just received is not long enough to completely overwrite the old contents.It’s not echoing back the extra data because when you send the packet, the socket obeys
packet.getLength(), which controls how many bytes are to be sent.You can either:
Change your showMessage invocation to:
Any of those should fix it.