如果您正在谈论 Java ServerSocket,那么它没有任何listen
方法,大概是因为它与客户端套接字不同。在这种情况下,一旦它有一个端口号(在构造函数中或作为 a 的一部分bind
),它就可以继续自动侦听。
“常规”套接字(la BSD)具有侦听功能的原因是客户端和服务器使用相同的类型,因此您需要自己决定如何使用它。情况并非如此,ServerSocket
因为它是一个服务器套接字:-)
accept
老实说,我不确定你为什么会关心在调用之前监听是否处于活动状态。它是“监听”调用(在这个类中隐含)应该标记你的服务器开放业务。此时,通信层应该开始允许来电排队等待您来电accept
。这通常是它们的工作方式,将请求排队,以防您的程序在接受它们时有点慢。
至于为什么要这么做,其实应该是根据源码来的。在 OpenJDK6source/share/classes/java/net/ServerSocket.java
中,构造函数最终都调用了一个构造函数:
public ServerSocket(int port, int backlog, InetAddress bindAddr)
throws IOException {
setImpl();
if (port < 0 || port > 0xFFFF)
throw new IllegalArgumentException(
"Port value out of range: " + port);
if (backlog < 1)
backlog = 50;
try {
bind(new InetSocketAddress(bindAddr, port), backlog);
} catch(SecurityException e) {
close();
throw e;
} catch(IOException e) {
close();
throw e;
}
}
对bind
(同一文件)的调用如下:
public void bind(SocketAddress endpoint, int backlog) throws IOException {
if (isClosed())
throw new SocketException("Socket is closed");
if (!oldImpl && isBound())
throw new SocketException("Already bound");
if (endpoint == null)
endpoint = new InetSocketAddress(0);
if (!(endpoint instanceof InetSocketAddress))
throw new IllegalArgumentException("Unsupported address type");
InetSocketAddress epoint = (InetSocketAddress) endpoint;
if (epoint.isUnresolved())
throw new SocketException("Unresolved address");
if (backlog < 1)
backlog = 50;
try {
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkListen(epoint.getPort());
getImpl().bind(epoint.getAddress(), epoint.getPort());
getImpl().listen(backlog);
bound = true;
} catch(SecurityException e) {
bound = false;
throw e;
} catch(IOException e) {
bound = false;
throw e;
}
}
相关位是:
getImpl().bind(epoint.getAddress(), epoint.getPort());
getImpl().listen(backlog);
这意味着当您创建套接字时,bind
和 listen
都在较低级别完成。
所以问题不在于“它为什么突然出现在netstat
?”中?但是“为什么之前没有出现netstat
?”
我可能会将其归结为您的误读,或者netstat
. 除非您专门测试您没有调用过的套接字,否则前者更有可能accept
,这不太可能。