gpt4 book ai didi

java - ServerSocket 监听而不使用accept()

转载 作者:行者123 更新时间:2023-12-02 08:02:02 26 4
gpt4 key购买 nike

我目前正在参与学校的一个项目,我们正在构建一个在 Android 手机上使用的通信系统。为此,我们将使用一个向所有客户端打开套接字的服务器,使它们进行通信。

我以前做过几个聊天应用程序,没有任何套接字或线程处理问题,但这次,由于某种原因,它让我感到困惑。

问题是,一旦我启动 ServerSocket 对象 serverSocket = new ServerSocket(5000),应用程序就开始监听,而不是在 serverSocket.accept().

这是为什么?

一旦我使用以下方法:

public void startListen(String port) {
try {
serverSocket = new ServerSocket(Integer.parseInt(port));
portField.setEditable(false);
} catch (IOException e) {
printMessage("Failed to initiate serverSocket: " + e.toString());
}}

端口在命令提示符中显示为正在监听(使用 netstat)。如果我不调用它,该端口不会被列为监听。

TCP 0.0.0.0:5000 Computer:0 LISTENING

那么,在使用 ServerSocket 对象时我缺少什么吗?我使用 ServerSocket 的旧程序在调用 accept() 之前不会开始监听。

最佳答案

如果您谈论的是 Java ServerSocket,那么它没有 listen 方法,大概是因为它与客户端套接字不同。在这种情况下,一旦它有了端口号(在构造函数中或作为 bind 的一部分),它就可以继续自动监听。

“常规”套接字(BSD)具有监听的原因是因为客户端和服务器使用相同的类型,因此您需要自己决定如何使用它。 ServerSocket 的情况并非如此,因为它是一个服务器套接字:-)

老实说,我不确定您为什么会关心在调用 accept 之前监听是否处于 Activity 状态。 “监听”调用(在此类中是隐式的)应该标记您的服务器开始营业。此时,通信层应该开始允许传入调用排队等待您调用 accept。这通常是它们的工作方式,对请求进行排队,以防您的程序接受请求有点慢。

<小时/>

至于为什么这样做,实际上根据源代码应该是这样的。在 OpenJDK6 source/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 的套接字,而这不太可能。

关于java - ServerSocket 监听而不使用accept(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13098771/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com