Java 使用线程的多客户端简单聊天(非 GUI)服务器

Multi Client Simple Chat(non-GUI) Server in Java using threads

我不知道如何阻止消息在客户端的屏幕上出现两次。

实际输出应该是这样的:

运行代码的步骤:
1. 运行一台终端服务器
2. 运行两个不同终端上的两个客户端

当我 运行 Server - main 方法创建一个 Server 对象时:

public static void main(String[] args) throws IOException {
            Server server = new Server();
    }

服务器构造函数:

Server() throws IOException {
            Date dNow = new Date();
            System.out.println("MultiThreadServer started at " + String.format("%tc", dNow));
            System.out.println();

            ServerSocket server = new ServerSocket(8000);
            ClientSockets = new Vector<Socket>();


            while (true) {
                    Socket client = server.accept();
                    AcceptClient acceptClient = new AcceptClient(client);
                    System.out.println("Connection from Socket " + "[addr = " + client.getLocalAddress() + ",port = "
                                    + client.getPort() + ",localport = " + client.getLocalPort() + "] at "
                                    + String.format("%tc", dNow));
                    System.out.println();
                    //System.out.println(clientCount);

            }
            //server.close();
    }

我正在使用套接字连接到服务器。这是我的服务器代码。

Server.java

import java.io.IOException;
import java.net.*;
import java.util.Vector;
import java.io.*;
import java.util.*;
import java.io.DataInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.text.*;
import java.util.Scanner;



public class Server {
    static Vector<Socket> ClientSockets;
    int clientCount = 0;
    //int i = 0;


    Server() throws IOException {
            Date dNow = new Date();
            System.out.println("MultiThreadServer started at " + String.format("%tc", dNow));
            System.out.println();

            ServerSocket server = new ServerSocket(8000);
            ClientSockets = new Vector<Socket>();


            while (true) {
                    Socket client = server.accept();
                    AcceptClient acceptClient = new AcceptClient(client);
                    System.out.println("Connection from Socket " + "[addr = " + client.getLocalAddress() + ",port = "
                                    + client.getPort() + ",localport = " + client.getLocalPort() + "] at "
                                    + String.format("%tc", dNow));
                    System.out.println();
                    //System.out.println(clientCount);

            }
            //server.close();
    }

    public static void main(String[] args) throws IOException {
            Server server = new Server();
    }

    class AcceptClient extends Thread {
            Socket ClientSocket;
            DataInputStream din;
            DataOutputStream dout;

            AcceptClient(Socket client) throws IOException {
                    ClientSocket = client;
                    din = new DataInputStream(ClientSocket.getInputStream());
                    dout = new DataOutputStream(ClientSocket.getOutputStream());

                    //String LoginName = din.readUTF();
                    //i = clientCount;
                    clientCount++;
                    ClientSockets.add(ClientSocket);
                    //System.out.println(ClientSockets.elementAt(i));
                    //System.out.println(ClientSockets.elementAt(1));

                    start();
            }

            public void run() {

                            try {
                                    while (true) {
                                    String msgFromClient = din.readUTF();
                                    System.out.println(msgFromClient);
                                    for (int i = 0; i < ClientSockets.size(); i++) {
                                            Socket pSocket = (Socket) ClientSockets.elementAt(i);
                                            DataOutputStream pOut = new DataOutputStream(pSocket.getOutputStream());
                                            pOut.writeUTF(msgFromClient);
                                            pOut.flush();
                                    }
                            }

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

            }
    }

}

Client.java

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


public class Client implements Runnable{

    Socket socketConnection;
    DataOutputStream outToServer; 
    DataInputStream din;


    Client() throws UnknownHostException, IOException {

            socketConnection = new Socket("127.0.0.1", 8000);
            outToServer = new DataOutputStream(socketConnection.getOutputStream());
            din = new DataInputStream(socketConnection.getInputStream());


            Thread thread;
            thread = new Thread(this);
            thread.start();

            BufferedReader br = null;
            String ClientName = null;
            Scanner input = new Scanner(System.in);
            String SQL = "";
            try {
                    System.out.print("Enter you name: ");
                    ClientName = input.next();
                    ClientName += ": ";
                    //QUERY PASSING

                    br = new BufferedReader(new InputStreamReader(System.in));
                    while (!SQL.equalsIgnoreCase("exit")) {
                            System.out.println();
                            System.out.print(ClientName);

                            SQL = br.readLine();
                            //SQL = input.next();
                            outToServer.writeUTF(ClientName + SQL);
                            //outToServer.flush();
                            //System.out.println(din.readUTF());

                    }

            } catch (Exception e) {
                    System.out.println(e);
            }
    }

    public static void main(String[] arg) throws UnknownHostException, IOException {
            Client client = new Client();
    }


    public void run() {
            while (true) {
                    try {
                            System.out.println("\n" + din.readUTF());

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

            }
    }

}

你有这个的原因是因为你向服务器发送客户端在控制台中写入的任何内容,然后服务器将它发送回 所有 个客户端(包括发件人).

所以你在控制台中写了一条消息(你看到了),然后你作为客户端之一接收回来(你又看到了)。

一个简单的解决方法是不将刚刚收到的消息发送回客户端(他已经在控制台中看到了)。将此添加到 Server.AcceptClient#run 方法:

for (int i = 0; i < ClientSockets.size(); i++) {
    Socket pSocket = (Socket) ClientSockets.elementAt(i);

    if(ClientSocket.equals(pSocket)){
        continue;
    }
    ...