繁体   English   中英

多线程服务器/客户端聊天

[英]Multi-Threading Server/Client Chat

所以这是我在这里的第一篇文章,我目前正在尝试使用套接字编程制作一个Java客户端/服务器聊天应用程序。

我目前有服务器在等待客户端连接,然后将客户端的消息传递回客户端。 到目前为止,我已经尝试了不同的方法来使服务器不断侦听新客户端并将其连接,从而允许它们彼此发布和查看消息。

您能指出我正确的方向吗,我应该如何实现呢?


服务器

class TCPServer {
private ServerSocket serverSocket;
private int port;
String newLine = System.getProperty("line.separator");
public TCPServer(int port) {
    this.port = port;
}
public void begin() throws IOException {

    System.out.println("Starting the server at port: " + port);
    serverSocket = new ServerSocket(port);

    System.out.println("Waiting for clients... " + newLine);

    try {

        Socket connectionSocket = serverSocket.accept();

        DataOutputStream hello =
                new DataOutputStream(connectionSocket.getOutputStream());
        hello.writeUTF("You have successfully connected!" + newLine + "please type your      username");


        //A client has connected to this server. Get client's username
        String username = getUserName(connectionSocket);
        System.out.println(username + " has connected" + newLine);
        //Start chat method
        startChat(connectionSocket, username);
    } catch (Exception e) {
    }

}

public String getUserName(Socket connectionSocket) throws IOException {
    String clientUserName;
    // ArrayList clients = new ArrayList();


    BufferedReader userNameClient =
            new BufferedReader(new InputStreamReader(
            connectionSocket.getInputStream()));


    clientUserName = userNameClient.readLine();
    //clients.add(clientUserName);


    DataOutputStream greetingFromServer =
            new DataOutputStream(connectionSocket.getOutputStream());
    //writeUTF Caused incorrect key codes to appear at beginning of String
    greetingFromServer.writeBytes("Welcome " + clientUserName + ", please type your message" + newLine);


    return clientUserName;
}

public void startChat(Socket connectionSocket, String username) throws IOException {
    String clientSentence;
    String clientMessageOut;



    while (true) {
        //Socket connectionSocket = welcomeSocket.accept();

        BufferedReader inFromClient =
                new BufferedReader(new InputStreamReader(
                connectionSocket.getInputStream()));
        DataOutputStream outToClient =
                new DataOutputStream(connectionSocket.getOutputStream());



        //Loops to check if client message is not empty
        while ((clientSentence = inFromClient.readLine()) != null) {
            outToClient.writeBytes(username + ": " + clientSentence + newLine);
            if (clientSentence.equals("close")) {
                System.out.println(username + " has left the server");
            }

        }
    }
}

public static void main(String[] args) throws Exception {
    int port = 6788;

    TCPServer welcomeSocket = new TCPServer(port);
    welcomeSocket.begin();


}

}


客户

class TCPClient {

public static void main(String[] args) throws Exception {
    String sentence;
    String modifiedSentence;
    boolean keepConnection = true;
    int port = 6788;
    Scanner inFromUser = new Scanner(System.in);

    Socket clientSocket = new Socket("localhost", 6788);
    //System.out.println("You are connented to server"+ '\n'+"Please enter your username: ");
    String newLine = System.getProperty("line.separator");

    //Recieve greeting message
    InputStream messageFromServer = clientSocket.getInputStream();
    DataInputStream in =
            new DataInputStream(messageFromServer);
    System.out.println("FROM SERVER: " + in.readUTF());


    DataOutputStream outToServer =
            new DataOutputStream(clientSocket.getOutputStream());
    BufferedReader inFromServer =
            new BufferedReader(new InputStreamReader(
            clientSocket.getInputStream()));

    while ((sentence = inFromUser.nextLine()) != null) {
        outToServer.writeBytes(sentence + '\n');
        modifiedSentence = inFromServer.readLine();
        System.out.println("sentence = " + sentence);
        System.out.println(modifiedSentence);
        if (sentence.equals("close")) {
            System.out.println("You have left the server");
            outToServer.writeBytes("close" + newLine);
            break;
        }
    }
    clientSocket.close();
}

}

您可以使用while(true){}while((socket = serverSocket.accept()) != null)来使服务器无限循环。

为了使服务器能够连接到多个客户端,可以创建一个循环,在其中接受新的连接:

while (true) {
    try {
        Socket connectionSocket = serverSocket.accept();
        ...
    } 
    ...
}

为了保持响应速度,您可以在新线程中与每个客户端一起使用,也可以维护线程池并为每个新连接向其提交任务。

这是一个示例( 取自ServerSocketEx )如何执行此操作。 ServerSocketEx扩展了ServerSocket,但这只是为了易于使用。 super.accept所有代码都与您的问题super.accept

正如其他人所建议的,您应该在一个循环中调用try()catch(IOException ...); 因此,如果您选择关闭ServerSocket,则可以将其关闭

public Socket accept() throws IOException {
    Socket s = super.accept();
    if (getSocketRunnerFactory() != null) {
        SocketRunner runner = getSocketRunnerFactory().createSocketRunner(s);
        if (executor != null) {
            Future f = 
                executor.submit(runner);
            if (futures != null) futures.add(f);
        }
        else {
            Thread t = new Thread(runner);
            t.start();
        }
    }
    return s;
}

暂无
暂无

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

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