等待 ServerSocket 的 accept() 方法将套接字置于“监听”模式

4

我需要一个简单的客户端-服务器通信,以便实现单元测试。

我的步骤:

  1. 创建服务器线程
  2. 等待服务器线程将服务器套接字放入监听模式(serverSocket.accept())
  3. 创建客户端
  4. 发出一些请求,验证响应

基本上,我在步骤#2遇到了问题。我找不到一种方法来在服务器套接字被设置为“监听”状态时通知我。在这种情况下,对“accept”的异步调用将会起作用,但是Java不支持这一点(根据文档,它似乎仅支持异步通道,而这些与“accept()”方法不兼容)。

当然,我可以使用简单的“sleep”,但这并不是生产代码的解决方案。

因此,总结一下,我需要检测ServerSocket何时已经进入监听模式,而不使用睡眠和/或轮询。

2个回答

7
一旦构造了ServerSocket对象,套接字就会进入监听状态,而不是在调用accept时。只要在ServerSocket构造函数完成后创建客户端,就不会有问题。连接将被接受并在内部排队,直到调用accept
以下是一些演示代码:
ServerSocket serverSocket = new ServerSocket(12345);
Thread.sleep(10000);
Socket socket = serverSocket.accept();

在调用 accept 方法之前的 10 秒钟,操作系统的 netstat 命令会显示服务器套接字处于 "LISTENING" 状态,客户端可以连接该套接字。如果在这 10 秒钟内有客户端连接,连接将被排队,在最终调用 accept 方法时,它会立即返回排队的 Socket 对象。

是的,你说得对。奇怪的是文档上没有提到这一点。但这可能是因为它是实现特定的(或仅适用于TCP协议)。 - inazaruk
@inazaruk 文档在多个地方提到了后备队列。 - user207421

-1

为什么在调用accept()之前不发送单个字符?

connectionAccepted = true;
loc.notify();
socket.accept();

为确保套接字已准备就绪,请在您的“客户端”代码中添加一个微小的延迟:
wait();
// we are here when notify is called.
Thread.sleep(10); // 10 ms
startTest();

你甚至可以做得更好:创建一个循环,尝试使用微小的延迟在套接字上进行“ping”。在这种情况下,您将尽可能快地开始测试。

嗯,这个解决方案与简单的sleep()一样存在问题。在sleep过期后,不能保证服务器套接字已经进入监听模式。尽管概率比使用简单的sleep()更高。 - inazaruk
在网络编程中添加睡眠时间并不能解决问题,只会延迟问题的出现。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接