开发者

How do I send a message over multiple threads in Java?

I made a simple chat server and client and the client will send text to the server, and the server will only send it back to the client that sent it to it. I want it to send to all the clients instead of just that one.

Server:

import java.io.IOException;
import java.net.ServerSocket;

public class Server {

    public static void main(String[] args) throws IOException {
        ServerSocket s = null;
        boolean listening = true;
        try {
            s = new ServerSocket(5555);
        } catch (IOException e) {
            e.printStackTrace();
        }

        while(listening)
            new ServerThread(s.accept()).start();

    }

}

Thread:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ServerThread extends Thread {

    private Socket sock = null;

    public ServerThread(Socket socket) {
        super("Server Thread.");
        this.sock = socket;
    }

    public void run() {

        PrintWriter out = null;
        BufferedReader in = null;

        try {
            System.out.println(sock.getInetAddress() + " has joined.");
            out = new PrintWriter(sock.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(sock.getInputStream()));

            String input;

            while((input = in.readLine()) != null) {
                System.out.println(input);
                out.println(input);
            }

            in.close();
            out.close();
            sock.close();

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

    }

}

Client:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client 
{
    public static void main(String[] args) throws IOException {
        Socket sock = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try {
            sock = new Socket("127.0.0.1", 5555);
            out = new PrintWriter(sock.getOutputStream(), true);
            in = new BufferedReader(
                    new InputStreamReader(sock.getInputStream()));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        BufferedReader stdIn = new BufferedReader(new InputS开发者_Python百科treamReader(
                System.in));
        String userInput;


        while ((userInput = stdIn.readLine()) != null) {    
            out.println(userInput);
            System.out.println(in.readLine());
        }

        out.close();
        in.close();
        sock.close();
    }

}


Have your server keep List<ServerThread>. Have a void sendAll(String) method on the Server that can be accessed by the ServerThreads and when they get information, that sendAll() method tells each ServerThread to send out their information.

What you're looking at doing though will require some asynchronous work (and is most certainly not trivial!)


Well, briefly: you're creating those ServerThreads and starting them, but you're not keeping track of them in any way. Imagine if each time you created one, you put it in a HashSet. Then each time a client sent a String, you iterated over the Set and sent the String to each of the clients. A method sendMessage(String) in ServerThread would make this easier, of course.


  1. Change your client to have one thread for reading from the server plus one thread for reading from the keyboard.

  2. Create a function which allows server socket threads to communicate with each other and use synchronization so that only one thread is writing to each outputstream at one time. So in brief, create a list of server threads which is shared by all threads and move your PrintWriter into a field with a getter, so it can be accessed from outside.


glowcoder and Ernest Friedman-Hill seem to be giving good advice, but I wanted to add one thing: have you considered using the Observer pattern and java's default implementation of Observable?

The Server could extend the Observable object, and the ServerThread could implement the Observer interface. As you create new ServerThreads, register them with the Observable using

server.addObserver(serverThread);

The ServerThread will need to know about the Server it is linked to. Then whenever a client sends in a new message, instead of out.println(userInput) do the following:

synchronized (server) {
    server.setChanged();
    server.notifyObservers(userInput);
}

You also need to implement ServerThread.update(Observable o, Object update), in which you would get the serverThread's socket's output stream and write ((String) update) to it.

Note that this will use one thread to send messages to all the observers and will block other threads from processing their chats until it has sent to all observers.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜