簡體   English   中英

創建一個多線程Java Server聊天應用程序。

[英]Creating a Multi-threaded Java Server Chat App.

我正在嘗試在Java中實現多線程服務器聊天應用程序。
該程序創建了一個線程,並等待客戶端連接。 連接客戶端后,它將創建另一個線程並等待另一個客戶端連接。

這是我的ChatServer.java

package com.chat.server;



import java.io.InputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.InetAddress;
import java.net.ServerSocket;



/**
 * <p>The chat server program</p>
 * This class is a Thread that recieves connection
 * from different clients and handles them is separate
 * Thread.
 *
 * @author Aditya R.Singh
 * @version 1.0.0
 * @since 1.0.0
 */
class ChatServer extends Thread {

    private int port;                    // The port number to listen at.
    private String ip;                   // To store the IP address.
    private Socket socket;               // Socket connection with different clients.
    private InetAddress inet;            // Handling Client Address.
    private ServerSocket serverSocket;   // The server socket used by clients to connect.



    /**
     * This is solely intended for instantiation purpose.
     * 
     * @param PORT - The port number to listen for client requests
     */
    ChatServer(final int PORT) {


        /* Initiallizing all instance variables to null. */
        ip = null;
        inet = null;
        socket = null;
        serverSocket = null;

        /* Initiallizing the port number. */
        port = PORT;
    }



    /**
     * This method creates a connection between server and client.
     * 
     * @throws java.io.IOException
     */
    private void createConnection() throws IOException {

        serverSocket = new ServerSocket(port);  // Listen to the required port. 
        socket = serverSocket.accept();         // Accept the client connection.
    }



    /**
     * This method sets the IP address.
     */
    private void setIP() {

        inet = socket.getInetAddress();
        ip = new String(inet.getHostAddress());
    }



    /**
     * This method returns the IP address.
     *
     * @return IP address.
     */
    public String getIP() {

        return ip;
    }



    /**
     * This method checks if the socket has been connected
     * with any client.
     *
     * @return True if the client has been connected, else false
     */
    public boolean isConnected() {

        if(socket == null)
            return false;
        return true;
    }



    /**
     * This method returns the InputStream
     * from the Socket.
     * 
     * @return InputStream if Socket has been connected to the client, else null
     * @see java.io.InputStream
     */
    public InputStream getInputStream() throws IOException {

        if(socket == null)
            return null;
        return socket.getInputStream();
    }



    @Override
    public void run() {

        try {

            createConnection();
            setIP();
        } catch(IOException exception) {

            exception.printStackTrace();
        }
    }
}  

這是我的Server.java

package com.chat.server;



/** 
 * <p>The Server app</p> 
 * This is the controller for accepting connections.
 *
 * @author Aditya R.Singh 
 * @version 1.0.0
 * @since 1.0.0
 */
public class Server {


    /**
     * The port at which clients will connect.
     */
    public static final int PORT = 6005;          



    /**
     * For instantiation purpose.
     */
    public Server() {


    }



    public static void main(String[] args) {


        /* Keep accepting connections. */
        while(true) {

            ChatServer chat = new ChatServer(PORT); // Connecting port.
            chat.start();

            while(!chat.isConnected())
                /* This is a false loop. Intended to keep running unless another client is not requesting to connect. */;

            System.out.println("We connected to: "+chat.getIP());   
        }
    }
}  

該代碼可以正常編譯。
以以下方式運行代碼:

java com.chat.server.Server  

似乎該程序正在偵聽客戶端進行連接。 但是,在連接到客戶端之后,應該打印該客戶端的IP地址,然后為另一個客戶端創建另一個線程。 但是,它不會顯示客戶端的IP。

這是我的Client.java

package com.chat.client;



import java.net.Socket;
import java.io.IOException;



public class Client {

    public static void main(String[] args) {

        Socket socket = null;


        try {

            socket = new Socket("127.0.0.1", 6005);
            System.out.println("Socket connected.");
        } catch(IOException ex) {

            ex.printStackTrace();
        }
    }
}  

客戶端連接到服務器,必須打印Socket connected 客戶這樣做。 客戶端工作正常:

java com.chat.client.Client  
Socket connected.  

但是服務器應用程序不會打印客戶端的IP地址。 為什么這樣?

這是比賽條件。 socket = serverSocket.accept(); 導致while(!chat.isConnected())循環在調用方法“ setIP()”之前終止。 一種驗證此問題原因的快速方法是更改​​此方法:

public boolean isConnected() {
    if(socket == null)
        return false;
    return true;
}

public boolean isConnected() {
    if(socket == null || ip == null)
        return false;
    return true;
}

為了解決此問題,您應該確保設置IP的代碼和檢查其是否已連接的代碼使用synchronized關鍵字。 另外,請注意while(!chat.isConnected())循環沒有暫停運行,這意味着它會占用盡可能多的CPU ...這絕對不好。

查看@Michael Petch發布的鏈接,以正確實現聊天服務器。

這不是完整的代碼

package demo;

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



public class MultithreadedServer {

    public static final int PORT = 10000;

    public static void main(String[] args) {
        try(ServerSocket server = new ServerSocket(PORT)) {
            while(true){
                Socket connection = server.accept();
                Thread client = new ClientThread(connection);
                client.start();
            }
        } catch (IOException ex) {
            System.out.println("Error start server");
        }
    }

}

class ClientThread extends Thread {
    private Socket connection;

    public ClientThread(Socket connection) {
        this.connection = connection;
    }

    @Override
    public void run(){
        //Do communication with client
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM