尝试做一个回显客户端的广播服务器

时间:2018-06-30 14:42:53

标签: java sockets server

我正在尝试在一个服务器和多个客户端的情况下进行简单的群聊。 目的是当客户端将消息发送到服务器时,服务器只是将该消息发送回所有其他客户端。我让服务器将他写的消息发送给所有客户端,但他没有发送客户端消息。

服务器代码:

package Group;
import java.net.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.*;

public class GroupServer extends Thread {
    private ServerSocket server;
    protected List<ClientHandler> clients;

    public static void main(String[] args) throws IOException {
        new GroupServer(9876);
    }

    public GroupServer(int port) {
        try {
            this.server = new ServerSocket(port);
            System.out.println("New server initialized!");
            clients = Collections.synchronizedList(new ArrayList<ClientHandler>());
            this.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public void run() {
    while (true) {
        try {
            Socket client = server.accept();
            System.out.println(client.getInetAddress().getHostName() + " connected");
            ClientHandler newClient = new ClientHandler(client);
            clients.add(newClient);
            new SendMessage(clients);

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

class ClientHandler {
protected Socket client;
protected PrintWriter out;
protected DataInputStream in;

public ClientHandler(Socket client) {
    this.client = client;
    try {
        this.out = new PrintWriter(client.getOutputStream());
        this.in = new DataInputStream(client.getInputStream());

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

class SendMessage extends Thread {
    protected List<ClientHandler> clients;
    protected String userInput;
    protected String sendMessage;
    protected BufferedReader stdIn;
    protected DataInputStream in;

    public SendMessage(List<ClientHandler> clients) {
        this.clients = clients;
        this.userInput = null;
        this.start();
    }

    public void run() {
        System.out.println("New Communication Thread Started");
        if (clients.size() == 1) {
            System.out.println("Enter message:");
        }
        try {
            if (clients.size() > 0) {
                this.stdIn = new BufferedReader(new InputStreamReader(System.in));

                while ((this.userInput = stdIn.readLine()) != null) {
                    if (userInput != null & userInput.length() > 0) {
                        for (ClientHandler client : clients) {
                            sendMessage = client.in.readUTF();
                            client.out.println(sendMessage);
                            client.out.flush();
                        Thread.currentThread();
                        Thread.sleep(1 * 1000);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

客户端代码:

package Group;
import java.net.*;
import java.io.*;
import java.util.logging.*;

public class GroupClient {
protected Socket client;
protected BufferedReader in;

public static void main(String[] args) {
    new GroupClient("Localhost", 9876);
}

public GroupClient(String hostName, int ip) {
    try {
        this.client = new Socket(hostName, ip);
        this.in = new BufferedReader(new InputStreamReader(
                this.client.getInputStream()));
        String buffer = null;
        while ((buffer = in.readLine()) != null) {
            System.out.println(buffer);
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}       
}

我认为错误出在服务器上,更确切地说是在SendMessage类上。 谢谢您的关注。

1 个答案:

答案 0 :(得分:0)

对于所有客户端,您只有一个线程“ SendMessage”。

第一次循环调用client.in.readUTF()时,线程将阻塞,直到该客户端发送了一些东西。由于所有其他客户端均由同一线程处理。所有这些也都被阻止了。

每个客户端套接字只有一个线程,或者采用nio选择器方式(首选)。

还可以解决@jingx提到的问题。

对于同步数组列表,请使用CopyOnWriteArrayList。它专门用于此类用例。同步有助于并发添加和删除,但不能在并发迭代期间提供帮助。 CopyOnWriteArrayList解决了这个问题。