[英]Java - how can I check if the ServerSocket.accept()ed the connection?
我正在嘗試編寫簡單的服務器-客戶端聊天解決方案。 出於測試目的,我創建了一個由 2 個 serverThreads 組成的數組,它們負責從連接的客戶端發送和接收消息。
我希望服務器在連接的客戶端數量達到最大值后拒絕連接。 但是,即使服務器不接受連接,也會創建客戶端的套接字。 socket.isBound 和 isConnected 方法都返回真值。
所以回到主要問題。 當 ServerSocket 無法 .accept() 附加連接時,您有什么想法我怎么能拒絕客戶端連接?
這是 Server 類的代碼。
public class Server {
private ServerSocket serverSocket = null;
private ServerThread serverThread[] = new ServerThread[2];
protected volatile int clientCount = 0;
public Server (int port){
try {
System.out.println("Binding to port " + port + " ...");
serverSocket = new ServerSocket (port);
System.out.println("Binded to port " + port + ".");
} catch (IOException e) {
System.out.println("Failed binding to the port: " + e.getMessage());
}
}
public void addThread (Socket socket){
System.out.println ("Client connected at socket: " + socket);
serverThread[clientCount] = new ServerThread (this, socket);
try {
serverThread[clientCount].open();
serverThread[clientCount].start();
} catch (IOException e) {e.getMessage();}
}
public void waitForClient () {
boolean isLogPrinted = false;
while (true){
try {
if (clientCount < serverThread.length){
System.out.println ("Waiting for connection...");
isLogPrinted = false;
addThread (serverSocket.accept());
clientCount++;
System.out.println("Client count: " + clientCount);
}
else {
if (!isLogPrinted){
System.out.println("MAXIMUM NUMBER OF CLIENTS REACHED! (" + clientCount + ").");
isLogPrinted = true;
}
}
} catch (IOException e) {
System.out.println("Error while waiting for new clients to connect: " + e.getMessage());
}
}
}
public synchronized void broadcastMessages (String msg){
for (int i = 0; i < clientCount; i++)
serverThread[i].sendMessage(msg);
}
public static void main (String args[]){
Server server = new Server (4200);
server.waitForClient();
}
}
我希望服務器在連接的客戶端數量達到最大值后拒絕連接。
關閉服務器套接字。
但是,即使服務器不接受連接,也會創建客戶端的套接字。
socket.isBound
和isConnected
方法都返回真值。
正確。 這是因為 TCP 維護了一個“積壓隊列”,其中包含已完成但尚未被服務器應用程序接受的傳入連接。
所以回到主要問題。 當 ServerSocket 無法 .accept() 附加連接時,您有什么想法我怎么能拒絕客戶端連接?
當連接數達到最大值時關閉服務器套接字。
然而,由於積壓,這種技術永遠不會是完美的。 沒有完美的解決方案。 您可以讓服務器立即關閉多余的連接,但多余的客戶端在嘗試發送某些內容之前不會檢測到它。 如果您需要完美,您可能必須引入一個應用程序協議,服務器相應地發送諸如“接受”或“拒絕”之類的內容。
而不是 while true 在你的 waitForClient 方法中試試這個
private final int allowedClients = 10;
private int connectedClients = 0;
public void waitForClient () {
boolean isLogPrinted = false;
while (connectedClients <= allowedClients){
try {
if (clientCount < serverThread.length){
System.out.println ("Waiting for connection...");
isLogPrinted = false;
addThread (serverSocket.accept());
connectedClients++;
System.out.println("Client count: " + clientCount);
}
else {
if (!isLogPrinted){
System.out.println("MAXIMUM NUMBER OF CLIENTS REACHED! (" + clientCount + ").");
isLogPrinted = true;
}
}
} catch (IOException e) {
System.out.println("Error while waiting for new clients to connect: " + e.getMessage());
}
} }
我知道現在回答已經很晚了,但我認為這會對很多人有所幫助。 您可以通過以下代碼檢查現有套接字(如果有)。
SocketAddress socketAddress = new InetSocketAddress("localhost", 8091);
Socket socket = new Socket();
ServerSocket serverSocket = null;
try {
socket.connect(socketAddress);
} catch (IOException e) {
e.printStackTrace();
}
if(socket == null) {
try {
serverSocket = new ServerSocket(8091);
} catch (IOException e) {
e.printStackTrace();
}
}
如果在同一端口和 IP 上沒有找到活動套接字,那么它將啟動一個新的服務器套接字,或者您可以更改它僅啟動套接字,否則您可以連接到現有套接字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.