Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I've created a Java server with sockets, just how do print to ALL sockets?

I've been trying this for a while, and I want multiple clients to recieve multiple inputs simultaneously.
There is one problem, I want the server to print "Hi" to all clients if one client says 'print2all Hi'.
I know how to process it to print it, just to print to ALL clients is the problem.

Here's what I have so far.
Server

try{
    try{
        server = new ServerSocket(25565);
    } catch (Exception e){
        e.printStackTrace();
    }
    while (isListening){
        new SocketThread(server.accept()).start();
    }
    server.close();
} catch (Exception e){
    e.printStackTrace();
}

SocketThread

try {
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    String inputLine, outputLine;
    Processor kkp = new Processor();
    out.println("Hi!");

    while ((inputLine = in.readLine()) != null) {
        outputLine = kkp.Proccess(inputLine,this.socket);
        out.println(outputLine);
    }
    out.close();
    in.close();
    socket.close();

} catch (IOException e) {
    e.printStackTrace();
}

Client

            Processor p = new Processor();
            socket = new Socket("localhost",25565);
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                
            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
            String fromServer;
            String fromUser;
            out.println("print2all Hi")            
            socket.close();
like image 855
KeirDavis Avatar asked Sep 23 '12 08:09

KeirDavis


People also ask

How would you build client servers that communicate using sockets?

Java socket server exampleCreate a ServerSocket , specifying a port to listen on. Invoke the ServerSocket 's accept() method to listen on the configured port for a client connection. When a client connects to the server, the accept() method returns a Socket through which the server can communicate with the client.

How do you handle multiple clients in socket programming in java?

The method printToALLClients() sends the output to each client in the thread. For the Client, we use the Socket class and initiate the connection to a server bypassing the IP address and port number. We use the Scanner to get the input from the user and send the data to the server using the PrintWriter object.

How does a server socket work in java?

ServerSocket is a java.net class that provides a system-independent implementation of the server side of a client/server socket connection. The constructor for ServerSocket throws an exception if it can't listen on the specified port (for example, the port is already being used).


2 Answers

First you need to keep track of all connected clients:

final List<SocketThread> clients = new ArrayList<>();

while (isListening){
    SocketThread client = new SocketThread(server.accept()).start();
    clients.add(client);
}

Having such list if one client receives "print2all Hi" it simply iterates over all clients and sends message to each of them. To do this you'll most likely have to expose some method on SocketThread that will access client socket. This means you'll have to change out variable to field.

Alternative approach is to keep a list of client sockets. But this breaks encapsulation badly. Also you might run into nasty IO/thread-safety issues if sockets are exposed directly. Better hide them behind some API (like SocketThread method) and do the synchronization properly inside.

like image 156
Tomasz Nurkiewicz Avatar answered Oct 04 '22 04:10

Tomasz Nurkiewicz


A full implementation of what you are looking.

Server

package tcpserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TCPServer {

    private int serverPort = 25565;
    private ServerSocket serverSocket;
    private List<ConnectionService> connections = new ArrayList<ConnectionService>();

    public TCPServer() {
        try {
            serverSocket = new ServerSocket(serverPort);
            System.out.println("Waiting...");
            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("Connected: " + socket);
                ConnectionService service = new ConnectionService(socket);
                service.start();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        new TCPServer();
    }

    class ConnectionService extends Thread {

        private Socket socket;
        private BufferedReader inputReader;
        private PrintWriter outputWriter;
        //private String username;

        public ConnectionService(Socket socket) {
            this.socket = socket;
            try {
                inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                outputWriter = new PrintWriter(socket.getOutputStream(), true);
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }

        @Override
        public void run() {
            while (true) {
                try {
                    String receivedMessage = inputReader.readLine();
                    System.out.println(receivedMessage);
                    StringTokenizer stoken = new StringTokenizer(receivedMessage);
                    String fargument = stoken.nextToken();
                    if (fargument.equals("print2all")) {
                        this.sendToAnyone(stoken.nextToken());
                    }
                } catch (IOException ex) {
                    Logger.getLogger(TCPServer.class.getName()).log(Level.SEVERE, null, ex);
                } catch (NullPointerException e) {
                    System.out.println(e.getMessage());
                } finally {
                    outputWriter.close();
                }

            }
        }

        protected void sendMessage(String message) {
            outputWriter.println(message);
        }

        private void sendToAnyone(String message) {

            for (ConnectionService connection : connections) {
                connection.sendMessage(message);
            }
        }
    }
}

Client

package tcpclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class tcpClient extends javax.swing.JFrame {

    private Socket socket;
    private BufferedReader inputReader;
    private PrintWriter outputWriter;

    public tcpClient() {
        connectToServer();
    }

    private void connectToServer() {
        try {
            socket = new Socket(InetAddress.getByName("localhost"), 25565);
            inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            outputWriter = new PrintWriter(socket.getOutputStream(), true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        new Thread() {
            @Override
            public void run() {
                receiveData();
            }
        }.start();
    }

    private void receiveData() {
        try {
            while (true) {
                System.out.println(inputReader.readLine());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendData(String messageToSend) {
        outputWriter.println(messageToSend);
    }

    public void closeSocket() {
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                tcpClient client = new tcpClient();
                client.sendData("print2all Hi");
                client.closeSocket();
            }
        });
    }
}
like image 28
giannis christofakis Avatar answered Oct 04 '22 03:10

giannis christofakis