'How do I send objects back and forth continuously across sockets in Java?

What I am trying to do here is create an application that will be a basic game, and first I have to get the networking functional. I'm struggling to send objects back and forth between server and client. The design I am trying to achieve is 2 processes with 2 threads each, the main thread and then a listener thread. I want the listener thread to listen for incoming objects, as this will be used for an event bus. Currently to get it working I'm using just a simple message class which holds a single string field called text. The issue I'm having is that the client listener thread doesn't seem to start, and the objects never get sent either way. Really struggling learning network programming here, any help is much appreciated.

Server side

package Server;

import java.net.*;
import java.util.List;

import Utilities.Message;

import java.io.*;

public class BattleshipServer 
{
    
    public static void executeThreadedServer(int port) throws Exception
    {
        ServerSocket server = new ServerSocket(port);
        System.out.println("Awaiting connection");
        Socket socket = server.accept();
        System.out.println("Connection established");
        
        BufferedReader kb = new BufferedReader(new InputStreamReader(System.in));
        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        
        //Start the listener thread
        ServerListener sListener = new ServerListener(kb, out, in);
        sListener.run();
        
        Message msg = new Message("temp");
        
        while(!msg.getText().equalsIgnoreCase("exit"))
        {
            msg = new Message(kb.readLine());
            out.writeObject(msg);
            out.flush();
        }
        
    }
}

------------------------------------------------------------------------------------------------------------

package Server;

import java.io.BufferedReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import Utilities.Message;

public class ServerListener implements Runnable 
{

    private BufferedReader keyBoard;
    private ObjectOutputStream out;
    private ObjectInputStream in;
    
    public ServerListener(BufferedReader keyboard, ObjectOutputStream out, ObjectInputStream in)
    {
        this.keyBoard = keyboard;
        this.out = out;
        this.in = in;
    }
    
    @Override
    public void run() 
    {
        System.out.println("Server listener started");
        try {
            while(true)
            {
                Message msg;
                
                while((msg = (Message)this.in.readObject()) != null)
                {
                    System.out.println(msg.getText());
                }
                
            }
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }

    }

}

Client Side

package Client;

import java.net.*;
import java.util.ArrayList;
import java.util.List;

import Utilities.Message;

import java.io.*;

public class BattleshipClient 
{
    
    public static void executeThreadedClient(String address, int port) throws Exception
    {
        Socket socket = new Socket(address, port);
        
        BufferedReader kb = new BufferedReader(new InputStreamReader(System.in));
        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
        
        ClientListener cListener = new ClientListener(kb,out,in);
        cListener.run();
        
        Message msg = new Message("temp");
        while(!msg.getText().equalsIgnoreCase("exit"))
        {
            msg = new Message(kb.readLine());
            out.writeObject(msg);
            out.flush();
        }
        socket.close();
    }
    
}

------------------------------------------------------------------------------------------------------------

package Client;

import java.io.BufferedReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import Utilities.Message;

public class ClientListener implements Runnable 
{
    
    private BufferedReader keyBoard;
    private ObjectOutputStream out;
    private ObjectInputStream in;
    
    public ClientListener(BufferedReader keyboard, ObjectOutputStream out, ObjectInputStream in)
    {
        this.keyBoard = keyboard;
        this.out = out;
        this.in = in;
    }

    @Override
    public void run() 
    {
        System.out.println("Client listener started");
        try
        {
            while(true)
            {
                Message msg = (Message)in.readObject();
                System.out.println(msg.getText());
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

}



Solution 1:[1]

Although your ClientListener and ServerListeners are implementing Runnable, they are not run in a separate thread. In your implementation, it is just another function call and therefore the code after the listener.run() never gets called.

So instead of doing:

ClientListener cListener = new ClientListener(kb,out,in);
cListener.run();

You need to do something like:

Thread clientThread = new Thread(new ClientListener(kb,out,in));
clientThread.start(); 

And on the server side you need to do something similar.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1