聊天程序:客户端到客户端聊天

时间:2014-05-10 13:10:40

标签: java sockets

目前,我正在使用Java进行这个迷你聊天程序,其中多个用户应该能够登录聊天程序并进行聊天。现在我的程序所做的是将用户(客户端)登录到服务器,他们所说的内容会被服务器回复。我想做的是能够直接发送请求与其他客户聊天。

我的想法是创建一个Hash映射,其中包含客户端及其套接字的用户名。当客户端请求与另一个客户端聊天时,它会在HashMap中查找该用户的用户名,如果另一个客户端同意聊天,则它会连接套接字。 我不确定如何实现这一点,而且我的程序只接受用户的一个输入并从服务器返回它,然后它停止我不知道为什么。我现在一直试图让这个工作一段时间,开始让我头疼。

以下是代码:

客户类:

package source;

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

public class Client implements Runnable {
    private Socket socket;
    private DataOutputStream dout;
    private DataInputStream din;
    // Constructor

    public Client() {
        // Code
    }

    public Client(String host, int port) {

        try {
            socket = new Socket(host, port);
            System.out.println("connected to " + socket);
            din = new DataInputStream(socket.getInputStream());
            dout = new DataOutputStream(socket.getOutputStream());
            new Thread(this).start();
        } catch (IOException ie) {
            System.out.println(ie);
        }
    }

    private void processMessage(String message) {
        try {
            dout.writeUTF(message);
        } catch (IOException ie) {
            System.out.println(ie);
        }
    }

    public void run() {
        try {
            while (true) {
                String message = din.readUTF();
                System.out.println(message);
            }
        } catch (IOException ie) {
            System.out.println(ie);
        }
    }

    public static void main(String[] args) throws IOException {
        while (true) {
            String prompt;
            Scanner clientPrompt = new Scanner(System.in);
            System.out.println("client> ");
            prompt = clientPrompt.next();
            if (prompt.equals("Emmanuel"))
                System.out.println("God With Us");
            else if (prompt.equals("goOnline")) {
                // Enter a host name
                // Enter a portNumber
                // Enter a userName
                String h, p, u;
                System.out.println("Enter hostname: ");
                h = clientPrompt.next();
                System.out.println("Enter portNumber: ");
                p = clientPrompt.next();
                System.out.println("Enter userName: ");
                u = clientPrompt.next();
                goOnline(h, p, u);
            } else if (prompt.equals("Exit")) {
                clientPrompt.close();
                System.exit(1);
            } else {
                System.out.println("Invalid Input, Try Again");
            }
        }
    }

    public static void goOnline(String host, String port, String userName) {
        int portNumber = Integer.parseInt(port);
        Client c = new Client(host, portNumber);
        c.processMessage("Username: " + userName);
        String prompt;
        Scanner clientPrompt = new Scanner(System.in);
        while (true) {

            prompt = clientPrompt.next();
            c.processMessage(prompt);
            c.run();
            if (prompt.equals("Exit")) {
                System.out.println("Bye Bye");
                clientPrompt.close();
            }
        }
    }
}

服务器类:

package source;

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

public class Server { // The ServerSocket we'll use for accepting new
                        // connections
    private ServerSocket ss;

    private HashMap<String, Socket> userInfo = new HashMap<String, Socket>();

    // A mapping from sockets to DataOutputStreams.
    private Hashtable<Socket, DataOutputStream> outputStreams = new Hashtable<Socket, DataOutputStream>();

    // Constructor and while-accept loop all in one.
    public Server(int port) throws IOException {
        // All we have to do is listen
        listen(port);
    }

    private void listen(int port) throws IOException {
        // ServerSocket
        ss = new ServerSocket(port);
        System.out.println("Listening on " + ss);
        while (true) {
            Socket s = ss.accept();
            System.out.println("Connection from " + s);
            DataOutputStream dout = new DataOutputStream(s.getOutputStream());
            DataOutputStream userInfo = new DataOutputStream(s.getOutputStream());
            outputStreams.put(s, dout);
            outputStreams.put(s, userInfo);
            new ServerThread(this, s);
        }
    }

    Enumeration<DataOutputStream> getOutputStreams() {
        return outputStreams.elements();
    }

    void sendToAll(String message) {
        for (Enumeration<DataOutputStream> e = getOutputStreams(); e.hasMoreElements();) {
            // Output Stream
            DataOutputStream dout = (DataOutputStream) e.nextElement();
            // Send Message
            try {
                dout.writeUTF(message);
            } catch (IOException ie) {
                System.out.println(ie);
            }
        }
    }

    // Remove socket,
    void removeConnection(Socket s) {
        // Synchronize
        synchronized (outputStreams) {
            // Tell the world
            System.out.println("Removing connection to " + s);
            // Remove it from hashtable
            outputStreams.remove(s);
            try {
                s.close();
            } catch (IOException ie) {
                System.out.println("Error closing " + s);
                ie.printStackTrace();
            }
        }
    }

    void addInfo(String user, Socket s) {
        userInfo.put(user, s);
    }

    // Main
    static public void main(String args[]) throws Exception {
        // Get port
        int port = Integer.parseInt(args[0]);
        // Create Server object
        new Server(port);
    }
}

ServerThread:

package source;

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

public class ServerThread extends Thread { // The Server that spawned us
    private Server server;
    private Socket socket;

    public ServerThread(Server server, Socket socket) {
        this.server = server;
        this.socket = socket;
        start();
    }

    public void run() {
        try {
            DataInputStream din = new DataInputStream(socket.getInputStream());
            while (true) {
                String message = din.readUTF();
                StringTokenizer stt = new StringTokenizer(message, " ");
                while (stt.hasMoreTokens()) {
                    String token = stt.nextToken();
                    if (token.equals("Username:")) {
                        String username = stt.nextToken();
                        server.addInfo(username, socket);
                    }
                }
                System.out.println("Sending " + message);

                server.sendToAll(message);
                if (message.equals("Exit")) {
                    System.out.println("Bye Bye");
                    server.removeConnection(socket);
                    System.exit(1);
                }
            }
        } catch (EOFException ie) {
        } catch (IOException ie) {
            ie.printStackTrace();
        } finally {
            server.removeConnection(socket);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我的程序只接受用户的一个输入并从服务器返回,之后停止我不知道为什么?

只需在客户端进行如下所述的一项更改即可解决上述问题。

public void run() {
    try {
        // while (true) { // remove an infinite loop that will block 
                          // the client thread to accept next message
        String message = din.readUTF();
        System.out.println(message);
        // }
    } catch (IOException ie) {
        System.out.println(ie);
    }
}

怀疑:(客户端)

  • 您已经开始了一个主题,那么为什么要直接调用run()方法。