Hello everyone,
I am in big trouble, actually, I am developing a chat in Java. I am still on the server part, but the problem is that when i am clicking on a button to instantiates a class, the whole program freeze, please help me to figure out this problem. I am using Netbeans as compiler. I just want to server to listen to the port when the button "btnServerOn" (in ServerConnect) is clicked.

Thanks in advance.


This is the "Server" class:

package ignisv4;
import java.io.*;
import java.net.*;


public class Server {

 int portNumber = 5000;
 String serverStatus;

 Socket clientSocket = null;
 PrintWriter out = null;
 BufferedReader in = null;

 public void setPortNumber(int PN){
        this.portNumber = PN;
 }
 
 public int getPortNumber(){
     return portNumber;
 }

 public String getServerStatus(){
     return serverStatus;
 }

 public void setServerStatus(String status){
     serverStatus = status;
 }

 public void createServer(){


     try{
        ServerSocket ss = new ServerSocket(portNumber);
          Socket incoming = ss.accept();
        //InputStream incomingStream = new InputStream();
        //incomingStream = incoming.getInputStream();

        BufferedReader in = new BufferedReader  (new InputStreamReader(incoming.getInputStream()));
        PrintWriter out = new PrintWriter  (incoming.getOutputStream(), true /* autoFlush */);


        boolean done = false;


        while (!done)
        {
          String messageline = in.readLine();
          if (messageline == null){
              done = true;
              setServerStatus("OFF");
          }
          else
          {
            out.println("Echo: " + messageline);
            setServerStatus("ON");

            if (messageline.trim().equals("BYE"))
              done = true;
              setServerStatus("OFF");
          }
        }

        incoming.close();

     }catch(Exception e){}

 }

This is the "ServerConnect" class:

package ignisv4;
public class ServerConnect extends javax.swing.JFrame {

    /** Creates new form ServerConnect */
    public ServerConnect() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        btnServerOn = new javax.swing.JButton();
        txtServerStatus = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        btnServerOn.setText("Server On");
        btnServerOn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnServerOnActionPerformed(evt);
            }
        });

        jLabel1.setText("Server Status");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(112, 112, 112)
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnServerOn)
                    .addComponent(txtServerStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 127, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(85, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(141, Short.MAX_VALUE)
                .addComponent(btnServerOn)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtServerStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addGap(110, 110, 110))
        );

        pack();
    }// </editor-fold>

    private void btnServerOnActionPerformed(java.awt.event.ActionEvent evt) {

        Server cs1 = new Server();
        cs1.createServer();
        txtServerStatus.setText(cs1.getServerStatus());

    }


    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ServerConnect().setVisible(true);
            
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JButton btnServerOn;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JTextField txtServerStatus;
    // End of variables declaration

}

Recommended Answers

All 19 Replies

ss.accept(); blocks its thread waiting for an incoming connection. Because you run that on the Swing thread everything gets blocked, and the whole program freezes until an incoming connection is received. You normally spawn a new Thread to run the accept() in.

ps. Its not a good idea to have a catch(Exception e){} because that guarantees that you won't see any errors! Put an e.printStackTrace(); in the catch so you cen see what's gone wrong after an error.

Thank you very much for your help James. But, I am new to socket programming, can you please give an idea on how to solve this problem please. What i should do ?? Please, i need this in order to continue working on my chat program!!

Many thanks in advance.

Briefly, you need to run your createServer in a new Thread. One way to do that is to make your server class extend Thread, and change the name of the createServer() method to run(). You can then call cs1.start(); to execute the run() method in a new Thread.
Have a look at the API for the Thread class.
There are also lots of good introductory materials for Java Threads on the web.

In addition to what James has said; if you want to be able handle more than one client you will need to create a thread for each client that connects.

Thanks again. I have done what you have said(that is creating a new thread) and the program doesn't freeze anymore.

But, now i am having a new problem, the :

txtServerStatus.setText("Status: " + cs1.getServerStatus());

is returning only null value. Its like the method run() is not running at all. Could you please help me of this. Thanks a lots.

Thanks for the tip jasimp but I am still learning, I am trying for only one client first then I will move to multithread chat.

At a guess - your call to getServerStatus() comes immediately after the start(), so it's executed in the current thread immediately. Only when that thread finishes executing will the new thread get to run and initialise the server.
If you declare String serverStatus; as String serverStatus = "Not yet started"; it may become clearer.

Thank you for your fast reply. I have done that ... I have put "None" instead of "Not yet started" just to check. But I am not getting the point.

According to the program, the method run() will be executed when I said cs1.start().

After the method run() have been executed, the value of the serverStatus should be either "ON" or "OFF" (see inside the while loop in the class Server)but still i am getting "Not yet started". Its like the method run() not running at all. I tried to put the setServerStatus("Test") outside the while-loop but i am still getting "Not Yet Started".

I could not figure whats wrong with my code. Many thanks in advance.

In your code, you set the status to ON or OFF when you process a connection from the client. Without a client to connect, those statuses will never get set, because the run() method will never get past the ss.accept(). Remember, the accept() method will just sit there waiting until there is a connection. Maybe try setting the status to "waiting for first connection" in the run() method just BEFORE the ss.accept()

I have done this but its not working, even if i put the setServerStatus just after "try":

public void run(){
try{
setServerStatus("Waiting for client connection...");

When I put the getServerStatus before the "try" its working, once inside the try, I get the "Not Yet Started". Do you think it has something to do with the tread ?

Sorry, don't know. Did you put the printStackTrace() in the catch like I said before? Try putting a few System.out.println("step 1 (2,3,4)"); statements into your run method so you can see exactly where it's getting to.
Try making a connection and see what happens. Just type
http://localhost:5000/ into your web browser. It won't do anything useful, but your code should accept the connection and echo the HTTP request for you.

Thanks, yeah I have put the printStackTrace() and i got this while running the program.

java.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
at java.net.ServerSocket.bind(ServerSocket.java:319)
at java.net.ServerSocket.<init>(ServerSocket.java:185)
at java.net.ServerSocket.<init>(ServerSocket.java:141)
at ignisv4.Server.run(Server.java:43)

When I clicked the button again, i got
java.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
at java.net.ServerSocket.bind(ServerSocket.java:319)
at java.net.ServerSocket.<init>(ServerSocket.java:185)
at java.net.ServerSocket.<init>(ServerSocket.java:141)
at ignisv4.Server.run(Server.java:43)

Anyway, thanks a lot, if its not working I will start all from scratch again.

NO don't give up now! You're almost there!
The exception is caused because previous test runs failed to close the socket properly and so it looks like it's still in use next time you try to open it. For as quick and dirty fix change the socket address to 5001, and keep changing it each time you get this problem. Fix it properly when your code is working a bit better. DON'T GIVE UP.

commented: Good advice. You have been very helpful in this thread. +9

Hello,
Thank you very much for your help. I have done the Client part but I can't get it to work. After running the server, i click connect on the client .. but then the client freeze as first time.

Then, again I have tried using Thread on the client also(as you suggest earlier) but after using Thread, afterwards nothing happen to the program. I have removed the Thread for the client side, here is a copy of the codes, check it please. Hope you will find a solution to my problem, thanks a lot for your precious time and help.

Is the server receiving the connection request?
Did you try using your browser as I suggested to check that the server is working properly?
The server waits for a line of input from the client before it sends its response, but the client code never sends one, so the server never responds, and the client waits forever.

Yes .. I have. When running localhost with the port 1234 and with the server supposedly "ON", I got "This webpage is not available.". I try to change the port every time but still don't know what to do.

You know, I am still learning thats why you may found silly mistakes in my codes(I am working hard on it to make it work .. I am developing it bit by bit to understand socket programming well), if their are some mistakes could you please correct it for me. Sometimes i got confuse. I am with these codes since monday.

Btw, could you explain to me how to write to the server from the client using the "PrintWriter output".

Thanks James.

could you explain to me how to write to the server from the client using the "PrintWriter output".
.

Same code as server sending to client, but other way round!

Did you add the System..printlines as I suggested to see whether the server gets the connection request?

Yeah ... I have put it but can't understand if its working or not. I am confuse, its seems to enter the while loop but the getServerStatus not working. I can't find the logic in it. Please do you have any other suggestions ?

OK, break the problem down into small pieces and fix them one at a time. I suggest you leave the whole GUI thing alone until the server and client code are working. Hard-code calls to the server & client code, and use System.out to see what's happening. When it all works properly, add in the user interface.
If your server code is entering the while loop then the connection HAS been made, so you're doing well. You still probably have the problem I described in my last post - so either get the client vto send something to the server, or simplify the server so it sends a response without waiting for the client to send something.
OK, it's now time for pre-dinner drinks here in France, so I'm going to sign off until tomorrow. Good luck, and remember - one thing at a time!

commented: A lot of patient help in this thread. +19

Ok .. Thanks a lot for your help. I will continue to work on it till morning !! Hope tomorrow I will be able to solve the problem by myself. If not i will post tomorrow. Again thank you very much for you time... this forum really rocks !! A+

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.