java - 发送给所有客户端java

标签 java client-server

我设置了一个经典的客户端/服务器,从客户端接收一个简单的数学问题,在服务器中计算结果,然后将结果发送回所有连接的客户端。但在客户端,我似乎在某个地方错过了阅读;来自第一个客户端的消息仅在我向第二个客户端输入内容后才返回到第二个客户端,反之亦然。我希望能够将所有消息发送给每个客户端,而无需先输入内容。

服务器代码:

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); 
        } 
    }
} 

客户端代码:

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();
    }
}

关于这个主题有很多答案,但似乎没有一个适合我的方式。

感谢所有建议。

** 我知道我的代码目前还不是很优雅,但在这个阶段,这只是让它工作然后从那里整理它的情况。

<小时/>

已解决

<小时/>

客户端的 while 循环需要这样修改

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();
            }
        }

我还对代码进行了一些其他调整,因此添加了变量等!

最佳答案

您需要同时处理输入和输出。一种选择是使用单独的线程。

现在,您的客户端和服务器按顺序锁定从一个到另一个的输入。

这种多线程需要在服务器和客户端上都存在。服务器每个连接的客户端需要两个线程(一个用于输入,一个用于输出),客户端也需要相同的线程,但仅用于与服务器的单个连接。

关于java - 发送给所有客户端java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33710618/

相关文章:

java - java.beans.PropertyDescriptor(String, Class) 的混淆行为

c - 我想在下面的代码中包含一个 for 循环,它可以每隔 n 秒连续发送数据 id、时间戳和消息

java - 无法在 AsyncTask 中启动新 Activity

java - 如何使用hadoop api在vm上运行的hadoop机器上创建目录

java - 服务器如何接收客户端的输入?

c++ - 使用 C++ 和标准 C 库以异步方式实现套接字连接读取超时处理的最佳方法

java - 语言之间的服务器客户端首选项

client-server - 为什么服务器无法获取客户端MAC地址,如客户端IP?

java - 使用 `String` 时,如何告诉 SuperCSV 映射空的 `CsvDozerBeanWriter` 属性?

java - 使用 Servlet 填充从 JSP 调用的弹出窗口