繁体   English   中英

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

[英]multiclient java client server chat

我正在尝试编写多客户端服务器聊天记录。 一切都应该在同一台计算机上运行,​​每个客户端在不同的Shell终端控制台中。 我在这边读了几个线程,有人说,我应该为每个连接的客户端在服务器上运行新线程。 因此,这就是我要做的。仍然,服务器正在从其控制台上的每个客户端打印消息,但是客户端只能看到他们编写的消息,而不能看到聊天中提交的每个消息。 我该怎么解决?

这是代码:服务器:

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





        }
    }
}   

服务器线程:

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

                    }   
            }


        }


}

和客户

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

    }
}

客户端需要两个线程:

  • 一个读取来自服务器的消息
  • 另一个线程从用户那里获取输入

第一个线程(来自服务器的读取器)仅读取传入消息并将其打印到控制台

第二个线程(服务器的写程序)接受用户输入并将其发送到服务器。

实际上,在您的代码中,客户端(主线程)上只有一个线程。

  1. 您必须实现ServerThread实例与服务器之间的通信(例如通过接口)。 必须通知服务器ServerThread获取的消息,然后将此消息转换为其他(先前已建立的)套接字(必须对其进行跟踪)。

  2. 您的客户端有两个S​​canner,但是其中一个实际上阻止了nextLine()调用中的另一个。 因此,您必须在单独的线程中运行扫描器之一。

以下代码对我有用,但必须考虑线程安全性:

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