I'm currently having some issues running this small battleship program I am working on. I have two GUI, one for the server and one for the client. When I click the "Start Server" jButton, the program will freeze until it receives something from the client side.

Image of the GUI if it helps:

GUI

I have no issues unfreezing it by starting the client program, my issue is, how can I make it so that it just doesn't freeze while waiting? thanks a lot.

package battleship;

import javax.swing.JOptionPane;
import java.io.IOException;
import java.util.Scanner;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;

/**
 *
 * @author ftonye
 */
public class BackGroundCom implements Runnable {

    private int port;
    private ServerSocket ss;
    private Socket cs;
    private Scanner reader;
    private PrintStream writer;
    public int missileIncomming;
    public int missileOutgoing;
    public Boolean dataToSend;
    InetAddress sa = null;

    public BackGroundCom(int port) {
        this.port = port;
        dataToSend = true;
        missileOutgoing = 100;

        startServer();
    }

    private void startServer() {
        try {
            sa = InetAddress.getLocalHost();
            System.out.println(sa);
        } catch (UnknownHostException ex) {
            Logger.getLogger(BackGroundCom.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Server started");

        try {
            ss = new ServerSocket(this.port);
            cs = ss.accept();
            JOptionPane.showMessageDialog(null, "Server accept connection from" + cs.getInetAddress().getHostAddress());
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }

        System.out.println("Server accept connection");

    }


Part of my BattleSea.java, which is where I click the button before it freezes:

btnStartServer = new JButton("Start Server");
        btnStartServer.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                com = new BackGroundCom(Integer.parseInt(txtPortNumber.getText().toString()));
                t = new Thread(com);
                t.start();


            }

        });

I am trying to understand how to get it to never freeze. Thanks

2 Answers

2
Steve On Best Solutions

I expect that it is the call cs = ss.accept(); that is blocking. This is going to block until the client connects to the server. You run this in response to pushing the button, because in your button action code, you construct a BackGroundCom, and that object's constructor calls startServer, which executes this accept() line directly.

It seems like you are trying to set up the BackGroundCom object so that what it does occurs in a background thread, but what I describe above all happens before you create and run the thread. Maybe what you want to do is move the startServer call into the run() method of the BackGroundCom object. I don't see a run() method in BackGroundCom, although it implements Runnable. I assume it's further down in the code. Without it, this code wouldn't even compile.

0
Doga Oruc On

Steve is right. ServerSocket.accept(); method will block until a connection is made. You have to put it inside another Thread so it won't block the EDT(Event Dispatching Thread). EDT is where your GUI runs.

public BackGroundCom(int port) {
    this.port = port;
    dataToSend = true;
    missileOutgoing = 100;

    new Thread(() -> (startServer()).start(); // run in new thread
}