Hot questions for Using Transmission Control Protocol in swing

Question:

i try to write a chat TCP. if i run file server and client independently, it is ok. But if i run by use other jframe, which has host button to run server, it will show a blank jframe

{
 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        FrmServer f=new FrmServer();
        f.setVisible(true);
    } 
}

this is FrmServer

 public FrmServer() throws HeadlessException {
    setTitle("Server");
    setLayout(new BorderLayout());

    addContent();
    addSend();

    setSize(400, 300);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    chat();
}
private ServerSocket serverInfo;
private Socket clientInfo;
private ObjectInputStream ois;
private ObjectOutputStream oos;

private void chat() {
    try {
        serverInfo = new ServerSocket(12345);

        clientInfo = serverInfo.accept();
        ois = new ObjectInputStream(clientInfo.getInputStream());

        oos = new ObjectOutputStream(clientInfo.getOutputStream());

        while (true) {
            String data = ois.readObject().toString();

            txtContent.append("Client :" + data + "\n");
        }
    } catch (Exception ex) {
    }
}

Answer:

Here is the modified code using a new thread (though not tried):

 public FrmServer() throws HeadlessException {
    setTitle("Server");
    setLayout(new BorderLayout());

    addContent();
    addSend();

    setSize(400, 300);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    chat();
}
private ServerSocket serverInfo;
private Socket clientInfo;
private ObjectInputStream ois;
private ObjectOutputStream oos;

private void chat() {
    Runnable runnable = new Runnable() {
        public void run() {
            try {
                serverInfo = new ServerSocket(12345);

                clientInfo = serverInfo.accept();
                ois = new ObjectInputStream(clientInfo.getInputStream());

                oos = new ObjectOutputStream(clientInfo.getOutputStream());

                while (true) {
                    String data = ois.readObject().toString();
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run(){
                            txtContent.append("Client :" + data + "\n");
                        }
                    });
                }
            } catch (Exception ex) {
            }

        }
    };
    //You can use a ThreadPool too.
    new Thread(runnable).start();
}

With Java 8 you can improve the syntax.

The important thing is you should not do anything time consuming on the Swing/AWT Event Dispatch Thread. Connecting to a server, waiting for reply certainly time consuming. Though the catch is, you cannot update the UI from other threads. So you need the SwingUtilities class to execute code on EDT.

Concurrency in Swing tutorial might help understanding the details.

Question:

I was writing a TCP chat program.

Here is my output. As you can see only first message from each peer is reaching the other end. Second message on wards are not displayed.

Here is my full code. You can run it. Where am I wrong?

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;

class chattcp extends JFrame {
    public static void main(String args[]){
        chattcp peer1=new chattcp("peer1",9999,9998);
        chattcp peer2=new chattcp("peer2",9998,9999);       
    }

    chattcp(String name,int lis,int snd){
        this.setVisible(true);
        this.setTitle(name);
        this.setLayout(null);
        this.setSize(500,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        TextField tf=new TextField();
        this.add(tf);
        tf.setBounds(10,20,100,40);

        TextArea ta=new TextArea();
        this.add(ta);
        ta.setBounds(10,80,400,400);
        ta.setEditable(false);
        ta.setFont(ta.getFont().deriveFont(20f));
        Button b=new Button("send");
        this.add(b);
        b.setBounds(130,20,60,40);
        b.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent a){
                try{
                    String s= tf.getText();
                    Socket skt=new Socket("localhost",snd);
                    DataOutputStream dos= new DataOutputStream(skt.getOutputStream());
                    dos.writeUTF(s);
                    ta.append("You :"+s+"\n");
                    tf.setText("");
                }
                catch(IOException e){
                    e.printStackTrace();
                }
            }
        });

        Thread receive=new Thread() {
                    public void run(){
                      try{
                        ServerSocket ser=new ServerSocket(lis);
                        Socket sktt=ser.accept();
                        DataInputStream dis= new DataInputStream(sktt.getInputStream());
                        while (true){
                            String s= dis.readUTF();
                            ta.append("Friend : "+s+"\n");
                        }
                      }catch(IOException e){e.printStackTrace();}
                    }
                };
        receive.start();

    }
}

Answer:

Everytime you click your send button you create a new socket and try to connect.

The problem is, once you send something, the socket is created, the serversocket accepts and starts the loop.

When you now write the second message, you are creating a new socket while the loop is still trying to read from the OutputStream from the old socket.

one solution to your problem is to close the serversocket after each read and create a new serversocket each iteration:

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;

public class chattcp extends JFrame {

public static void main(String args[]) {
    chattcp peer1 = new chattcp("peer1", 9999, 9998);
    chattcp peer2 = new chattcp("peer2", 9998, 9999);
}

chattcp(String name, int lis, int snd) {
    this.setVisible(true);
    this.setTitle(name);
    this.setLayout(null);
    this.setSize(500, 500);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    TextField tf = new TextField();
    this.add(tf);
    tf.setBounds(10, 20, 100, 40);

    TextArea ta = new TextArea();
    this.add(ta);
    ta.setBounds(10, 80, 400, 400);
    ta.setEditable(false);
    ta.setFont(ta.getFont().deriveFont(20f));
    Button b = new Button("send");
    this.add(b);
    b.setBounds(130, 20, 60, 40);
    b.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent a) {
            try {
                String s = tf.getText();
                Socket skt = new Socket("localhost", snd);
                DataOutputStream dos = new DataOutputStream(skt.getOutputStream());
                dos.writeUTF(s);
                ta.append("You :" + s + "\n");
                tf.setText("");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

    Thread receive = new Thread() {
        public void run() {
            try {
                while (true) {
                    ServerSocket ser = new ServerSocket(lis);
                    Socket sktt = ser.accept();
                    DataInputStream dis = new DataInputStream(sktt.getInputStream());

                    String s = dis.readUTF();
                    ta.append("Friend : " + s + "\n");

                    ser.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };
    receive.start();

}
}

a better solution would be to not always create a new socket, when you send something, but i am lazy and this solution is easier to edit your code to, so i just used it.

Question:

I got problem when my server connected to the client this exception is occur then my program not respond after connected. I use netbeans gui designer to generated code for gui class. I also comment the line number which show in exception below in my code for you guys considering. Everything work find before socket accept. Please help!

Exception in thread "Thread-0" java.lang.NullPointerException at serverui.ServerUi.StartServer(ServerUi.java:62) at serverui.ServerThread.run(ServerUi.java:19) at java.lang.Thread.run(Thread.java:745)

class ServerThread implements Runnable{

public void run(){
 try {
      ServerUi t = new ServerUi();
      t.StartServer(); //Line 19
     } catch (IOException ex) {
       //Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
            //Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}


public class ServerUi {
byte s = 0;
static ServerSocket serverSocket = null;
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
public static boolean checklisten = false;
static gui winframe = null;
public static void main(String[] args)throws IOException {

winframe = new gui();
serverSocket = new ServerSocket(10007);
Thread tserver = new Thread(new ServerThread());
tserver.start();

java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                winframe.setVisible(true);
            }
        });


    }

    public void StartServer()throws IOException, InterruptedException
    {

               winframe.displayMessage("Listening for Connection");
               clientSocket = serverSocket.accept();
               winframe.displayMessage("Connected");
               String inputLine;
               while(true){
                while((inputLine=in.readLine()) != null) // Line 62
                {

                    winframe.displayMessage("Server: "+ inputLine);
                    out.println(inputLine);

                    if(inputLine.equals("Bye."))
                    {
                        this.Closeconnection();
                        break;
                    }

                    if(winframe.checkdisconnectbtn == true)
                    {
                        this.Closeconnection();
                        break;
                    }

                }

               }
    }

Answer:

You never initialize your BufferedReader.

BufferedReader in = null;

... therefore this line fails with a NullPointerException:

while((inputLine=in.readLine()) != null) // Line 62

In general, whenever you see a NullPointerException, all you have to do is look at the line and check all the objects which are invoking methods for null.