简体   繁体   English

多客户端Java客户端服务器聊天

[英]multiclient java client server chat

I'm tryinna write a multiple client server chat. 我正在尝试编写多客户端服务器聊天记录。 Everything should run on the same computer, each client in the different shell terminal console. 一切都应该在同一台计算机上运行,​​每个客户端在不同的Shell终端控制台中。 I read couple of threads on this side, where people said, that I should run new thread on server for every single connected client. 我在这边读了几个线程,有人说,我应该为每个连接的客户端在服务器上运行新线程。 So that's what I've done.Still,Server is printing messages from every client on its console but clients can see only messages they wrote, not every message submitted on chat. 因此,这就是我要做的。仍然,服务器正在从其控制台上的每个客户端打印消息,但是客户端只能看到他们编写的消息,而不能看到聊天中提交的每个消息。 What should I do to fix it? 我该怎么解决?

Here is code: Server: 这是代码:服务器:

//package javauj.serwer;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;


public class Server {
    private static final int PORT_NUM = 5051;
    private static ServerSocket serS;
    private static Socket s;

    public static void main(String[] args) throws IOException{
        DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
        Calendar cal = Calendar.getInstance();
            System.out.println(df.format(cal.getTime())+" Server waiting on port "+PORT_NUM);
            try {
                serS = new ServerSocket(PORT_NUM);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }



        while(true){
            try {
                s = serS.accept();
                System.out.println("New user connected");
                    ServerThread st=new ServerThread(s);
                        st.start();


                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }   





        }
    }
}   

Server Thread: 服务器线程:

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Scanner;


public class ServerThread extends Thread {
    Socket socket=null;
    private Scanner sc;
    private PrintStream ps;
    public ServerThread(Socket s) {
        this.socket=s;

    }



        public void run(){
            DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
            Calendar cal = Calendar.getInstance();
            String response;    
                while(true){    
                try {
                        sc = new Scanner(socket.getInputStream());
                        ps = new PrintStream(socket.getOutputStream());
                } catch (IOException e) {
                            // TODO Auto-generated catch block
                        e.printStackTrace();
                }

                if((response=sc.nextLine())!=null){


                    System.out.println(df.format(cal.getTime())+" Napisal "+response);

                    ps.println(df.format(cal.getTime())+" Napisal :"+response);

                    }   
            }


        }


}

and Client 和客户

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;




public class Client {
    static Scanner sc;
    static Scanner sc2;
    static Socket s;
    static String response;
    public static void main(String[]args) throws UnknownHostException, IOException{
        String send;
        sc=new Scanner(System.in);  //client send scanner
        s = new Socket("127.0.0.1", 5051);
        sc2 = new Scanner(s.getInputStream());  //client response scanner
        PrintStream ps = new PrintStream(s.getOutputStream());

        while(true){

            System.out.println(">");    
            send = sc.nextLine();

            ps.println(send);       
            // I tried run new thread for responses
            //Thread thread = new Thread(new Runnable(){
                //public void run(){
                    //while(true){
                        response=sc2.nextLine();        
                        System.out.println(response);
                //  }   
                //}
            //});
        }

    }
}

You need two threads on the client side: 客户端需要两个线程:

  • one to read messages coming from the server 一个读取来自服务器的消息
  • another thread to get the input from the user 另一个线程从用户那里获取输入

The first thread (reader from server) simply reads incoming messages and print it to the console 第一个线程(来自服务器的读取器)仅读取传入消息并将其打印到控制台

The second thread (writer to the server) take user input and send it to the server. 第二个线程(服务器的写程序)接受用户输入并将其发送到服务器。

Actually in your code there is only one thread on the client (the main thread). 实际上,在您的代码中,客户端(主线程)上只有一个线程。

  1. You have to implement the communication (by an interface for example) between the instance of your ServerThread and the Server. 您必须实现ServerThread实例与服务器之间的通信(例如通过接口)。 The Server have to be notified about the message acquired by the ServerThread and then translate this message to the other (previously established) Sockets (which are must be tracked). 必须通知服务器ServerThread获取的消息,然后将此消息转换为其他(先前已建立的)套接字(必须对其进行跟踪)。

  2. Your client have two Scanners, but one of them actually blocks the other on nextLine() call. 您的客户端有两个S​​canner,但是其中一个实际上阻止了nextLine()调用中的另一个。 So you have to run one of the Scanners in separate thread. 因此,您必须在单独的线程中运行扫描器之一。

The following code works for me but the thread safety must be taken into account: 以下代码对我有用,但必须考虑线程安全性:

public interface MessageListener {
  void acceptMessage(String message);
}

public class Server {
  private static final int PORT_NUM = 5051;
  private static ServerSocket serS;
  private static List<PrintStream> sockets = new ArrayList<PrintStream>();
  public static void main(String[] args) throws IOException{
    DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
    Calendar cal = Calendar.getInstance();
    System.out.println(df.format(cal.getTime())+" Server waiting on port "+PORT_NUM);
    try {
        serS = new ServerSocket(PORT_NUM);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    MessageListener listener = new MessageListener() {
        @Override
        public void acceptMessage(String message) {
            Iterator<PrintStream> it = sockets.iterator();
            while (it.hasNext()) {
                PrintStream ps = it.next();
                ps.println("Have got message: " + message);
            }
        }
    };

    while(true){
        try {
            Socket s = serS.accept();
            sockets.add(new PrintStream(s.getOutputStream()));
            System.out.println("New user connected");
            ServerThread st=new ServerThread(s, listener);
            st.start();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }
}


public class ServerThread extends Thread {
  Socket socket=null;
  private Scanner sc;
  //private PrintStream ps;
  private final MessageListener listener;

  public ServerThread(Socket s, MessageListener listener) {
    this.socket=s;
    this.listener = listener;
  }

  public void run(){
    DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
    Calendar cal = Calendar.getInstance();
    String response;
    while(true){
        try {
            sc = new Scanner(socket.getInputStream());
            //ps = new PrintStream(socket.getOutputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if((response=sc.nextLine())!=null){


            System.out.println(df.format(cal.getTime())+" Napisal "+response);

            //ps.println(df.format(cal.getTime())+" Napisal :"+response);
            listener.acceptMessage(response);
        }
      }


  }


}

public class Client {
  static Scanner sc;
  static Scanner sc2;
  static Socket s;
  static String response;
  public static void main(String[]args) throws UnknownHostException, IOException{
    String send;
    sc=new Scanner(System.in);  //client send scanner
    s = new Socket("127.0.0.1", 5051);
    ResponseListener l = new ResponseListener(new Scanner(s.getInputStream()));
    Thread t = new Thread(l);
    t.start();

    PrintStream ps = new PrintStream(s.getOutputStream());

    while(true){

        System.out.println(">");
        send = sc.nextLine();

        ps.println(send);
    }

}

static class ResponseListener implements Runnable {
    private final Scanner scanner;

    ResponseListener(Scanner scanner) {
        this.scanner = scanner;
    }

    @Override
    public void run() {
        while (true) {
            response = scanner.nextLine();
            System.out.println(response);
        }
    }
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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