Java - 如何检查 ServerSocket.accept() 是不是连接?
Posted
技术标签:
【中文标题】Java - 如何检查 ServerSocket.accept() 是不是连接?【英文标题】:Java - how can I check if the ServerSocket.accept()ed the connection?Java - 如何检查 ServerSocket.accept() 是否连接? 【发布时间】:2017-03-04 23:55:29 【问题描述】:我正在尝试编写简单的服务器-客户端聊天解决方案。出于测试目的,我创建了一个包含 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();
【问题讨论】:
除非您向客户展示您的代码,否则您的问题将很难或无法回答。 @PresidentJamesMoveonPolk 显然不是。您只需要一个连接客户端。它不需要做任何其他事情。 Telnet 可以。 您的标题与您的问题不符。请澄清。 【参考方案1】:在你的waitForClient方法中尝试这个而不是while true
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());
【讨论】:
好的,但问题还是一样。即使服务器不接受连接,仍然可以毫无问题地创建客户端上的套接字。我正在寻找一种方法来检查服务器是否提交了 server.accept() 操作。 如果您在达到最大客户端数量后读取循环条件,服务器将停止侦听进一步的连接,最终客户端将无法连接 我提供的解决方案也阻止了 ServerSocket 的 .accept()ing 传入连接。 重点是client端的socket仍然是创建的,没有任何异常。当 ServerSocket 不接受连接时,为什么会发生这种情况? 如果条件为假,此代码将无意识地旋转 至少在其中添加一个睡眠。进行两次测试的意义让我无法理解。【参考方案2】:我希望服务器在连接的客户端数量达到最大值后拒绝连接。
关闭服务器套接字。
但是,即使服务器不接受连接,也会创建客户端的套接字。方法
socket.isBound
和isConnected
都返回真值。
正确。这是因为 TCP 维护了一个“积压队列”,其中包含已完成但尚未被服务器应用程序接受的传入连接。
回到主要问题。当 ServerSocket 无法 .accept() 附加连接时,您有什么想法如何拒绝客户端连接?
在连接数达到最大值时关闭服务器套接字。
但是由于积压,这种技术永远不可能完美。没有完美的解决方案。您可以让服务器立即关闭多余的连接,但多余的客户端在尝试发送某些内容之前不会检测到这一点。如果您需要完美,您可能必须引入一个应用程序协议,据此服务器会相应地发送“接受”或“拒绝”之类的内容。
【讨论】:
【参考方案3】:我知道回答这个问题已经很晚了,但我认为这会对很多人有所帮助。 您可以通过以下代码检查现有的套接字。
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 上没有找到活动套接字,那么它将启动一个新的服务器套接字,或者您可以更改它启动套接字,否则您可以连接到现有套接字。
【讨论】:
不回答以任何方式提出的问题。回答前请阅读问题。以上是关于Java - 如何检查 ServerSocket.accept() 是不是连接?的主要内容,如果未能解决你的问题,请参考以下文章