简体   繁体   English

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

[英]Chat Program: Client to Client Chat

Currently I'm working on this mini chat program in Java where multiple users should be able to log into the chat program and chat. 目前,我正在使用Java进行此小型聊天程序,其中多个用户应该能够登录到该聊天程序并进行聊天。 Right now what my program does is log in users (Clients) to the Server, and what ever they say gets echoed back by the Server. 现在,我的程序要做的是将用户(客户端)登录到服务器,然后他们所说的一切都会被服务器回显。 What I want to do is be able to send a request to chat with another client directly. 我想做的是能够发送直接与另一个客户端聊天的请求。

My idea was to create a Hash map that holds the username of the client and its socket. 我的想法是创建一个哈希映射,其中包含客户端的用户名及其套接字。 When a client requests to chat with another client it looks for that user's username in the HashMap and if the other client agrees to chat then it connects the sockets. 当一个客户端请求与另一个客户端聊天时,它将在HashMap中查找该用户的用户名,如果另一个客户端同意聊天,则它将连接套接字。 I'm not sure how to implement this and also my program only takes one input from the user and returns it from the Server and after that it stops I have no idea why. 我不知道如何实现它,我的程序也只从用户那里获取一个输入,然后从服务器返回它,然后它停止,我不知道为什么。 I've been trying to get this working for a while now, starting to give me headaches. 我一直在努力使它工作一段时间,开始让我头疼。

Here's the code: 这是代码:

Client Class: 客户类别:

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

Server Class: 服务器类别:

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

my program only takes one input from the user and returns it from the Server and after that it stops I have no idea why? 我的程序只接受用户的一个输入,然后从服务器返回它,此后停止我不知道为什么?

Just do one change as mentioned below at client side to resolve above issue. 只需在客户端进行如下所述的一项更改即可解决上述问题。

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

Doubt: (client side) 疑问:(客户端)

  • You have started a thread then why are you calling run() method directly. 您已经启动了线程,然后为什么要直接调用run()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM