[英]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.