简体   繁体   中英

send to all clients java

I have a classic client/server set up to take in a simple math problem from the client, calculate the result in the server and then send the result back to all connected clients. But on the client side it seems like I'm missing a read somewhere; the messages from first client are only returned to the second client after I input something into the second client and vice versa. I want to be able to send all messages to each client without having to input something first.

Sever code:

import java.net.*; 
import java.util.*;
import java.io.*; 

public class EchoServer2 extends Thread{

    protected Socket clientSocket;
    static String [] logs = new String[100];
    private static ArrayList<PrintWriter> writers = new ArrayList<PrintWriter>();
    static int arrayPos = 0;
    static int i;
    static String message;
    public static void main(String[] args) throws IOException{

        ServerSocket serverSocket = null; 
        try{ 
            serverSocket = new ServerSocket(10008); 
            System.out.println ("Connection Socket Created");
            try { 
                while (true)
                {
                    System.out.println ("Waiting for Connection");
                    new EchoServer2 (serverSocket.accept()); 
                }
            } 
            catch (IOException e) 
            { 
                System.err.println("Accept failed."); 
                System.exit(1); 
            } 
        } 
        catch (IOException e) 
        { 
            System.err.println("Could not listen on port: 10008."); 
            System.exit(1); 
        } 
        finally{
            try{
                serverSocket.close(); 
            }
            catch (IOException e)
            { 
                System.err.println("Could not close port: 10008."); 
                System.exit(1); 
            } 
        }
    }

    private EchoServer2 (Socket clientSoc){
        clientSocket = clientSoc;
        start();
    }

    public void run(){
        System.out.println ("New Communication Thread Started");

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

            String inputLine; 
            while ((inputLine = in.readLine()) != null) { //reading
                logs[arrayPos] = inputLine; //keep record of all commands sent to server
                arrayPos++; //update array position

                if (inputLine.equals("Bye.")) //break if client enters 'Bye."
                    break;
                if(inputLine.equals("Logs.")){ //print out contents of logs if any client enters 'Logs'
                    for(i=0; i<arrayPos; i++){
                        System.out.println("Log"+ i + ": " + logs[i]);
                        out.println("Log"+ i + ": " + logs[i]);
                    }         
                    break;
                } 

                int x, y, result;
                String num1, num2, operator;
                String [] splitStrings = inputLine.split(" ");
                num1 = splitStrings[0];
                x = Integer.parseInt(num1);
                operator = splitStrings[1];
                num2 = splitStrings[2];
                y = Integer.parseInt(num2);
                switch(operator){
                case "+":
                    result = x + y;
                    System.out.println ("Server: " + result); 
                    out.println(result);
                    for (PrintWriter writer : writers) {
                        if (writer == out)
                            continue;
                        writer.println(result);
                    }
                    break;
                case "-":
                    result = x - y;
                    System.out.println ("Server: " + result); 
                    out.println(result);
                    for (PrintWriter writer : writers) {
                        if (writer == out)
                            continue;
                        writer.println(result);
                    }
                    break;
                case "*":
                    result = x * y;
                    System.out.println ("Server: " + result); 
                    out.println(result);
                    for (PrintWriter writer : writers) {
                        if (writer == out)
                            continue;
                        writer.println(result);
                    }
                    break;
                case "/":
                    result = x / y;
                    System.out.println ("Server: " + result); 
                    out.println(result);
                    for (PrintWriter writer : writers) {
                        if (writer == out)
                            continue;
                        writer.println(result);
                    }
                    break;
                default:
                    System.out.println("Please enter a more simple equation using one of the 4 main operators i.e. '+, -, *, /'");
                    break;
                }
            }

            out.flush();
            out.close(); 
            in.close(); 
            clientSocket.close(); 
        } 
        catch (IOException e){ 
            System.err.println("Problem with Communication Server");
            System.exit(1); 
        } 
    }
} 

Client code:

import java.io.*;
import java.net.*;

public class EchoClient{
    public static void main(String[] args) throws IOException{
        String serverHostname = new String ("127.0.0.1");
        if (args.length > 0)
           serverHostname = args[0];
        System.out.println ("Attemping to connect to host " + serverHostname + " on port 10008.");
        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try{
            // echoSocket = new Socket("taranis", 7);
            echoSocket = new Socket(serverHostname, 10008);
            out = new PrintWriter(echoSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
        }catch (UnknownHostException e){
            System.err.println("Don't know about host: " + serverHostname);
            System.exit(1);
        } catch (IOException e){
            System.err.println("Couldn't get I/O for " + "the connection to: " + serverHostname);
            System.exit(1);
        }

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
        String userInput;
        System.out.println ("Type Message (\"Bye.\" to quit)");
        System.out.println("Enter a simple math equation i.e. 2 + 2 separated by a space…");

        while ((userInput = stdIn.readLine()) != null){
            out.println(userInput);
            userInput = in.readLine();
            System.out.println("echo: " + userInput);
            while(in.ready()){
                userInput = in.readLine();
                System.out.println("echo: " + userInput);
            }
            System.out.println("Enter a simple math equation e.g. 2 + 2 separated by a space…");

        }
        out.close();
        in.close();
        stdIn.close();
        echoSocket.close();
    }
}

There's quite a few answers on this topic but none seems to work for the way I'm doing it.

All suggestions appreciated.

** I know my code isn't very elegant at the moment but at this stage it's just a case of getting it working and then tidying it up from there.


Solved


The while loop on the client side needed to be altered as so

while(true){
            if(userInput == null){
                System.out.println("Input is null");
            }
            if(userInput.equals("Bye.")){
                break;
            }
            if(stdIn.ready()){//(userInput = stdIn.readLine()) != null){
                userInput = stdIn.readLine();
                out.println(clientID + "\t" + userInput);
                userInput = in.readLine();
                System.out.println("echo: " + userInput);
                System.out.println("Enter a simple math equation e.g. 2 + 2 separated by a space…");
                out.flush();
            }
            else if(in.ready()){
                userInput = in.readLine();
                System.out.println("echo: " + userInput);
                //System.out.println("Enter a simple math equation e.g. 2 + 2 separated by a space…");
                out.flush();
            }
        }

I've also made some other adjustments to the code hence why there's added variables etc!

You need to handle input and output concurrently. One option would be to use separate threads.

Right now your clients and server walk in lock step blocking on input from one to the other in sequence.

This multithreading needs to be on both the server and the client. The server will need two threads per connected client (one for input, one for output) and the clients will need the same but only for the single connection to the server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM