【问题标题】:Java nio connection is creating multiple socket level connections, Why?Java nio 连接正在创建多个套接字级别的连接,为什么?
【发布时间】:2013-07-31 11:23:07
【问题描述】:

我写了一个简单的java nio程序,如下所示

 public static void main(String[] args) throws IOException, InterruptedException {


    InetSocketAddress address = new InetSocketAddress("127.0.0.1",1001);
    Selector incomingMessageSelector = Selector.open();
    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.configureBlocking(false);   

// 到这里为止,代码创建了到端口 52209 和 52210 的前 2 个连接

    socketChannel.connect(address);
    socketChannel.register(incomingMessageSelector, SelectionKey.OP_CONNECT);
    socketChannel.register(incomingMessageSelector, SelectionKey.OP_WRITE);
    socketChannel.register(incomingMessageSelector, SelectionKey.OP_READ);

// 然后创建2个到1001端口的连接

    Thread.sleep(900000L);
}

我想了解为什么它会创建 4 个连接,而使用标准 TCP 阻塞库它往往会创建 2 个连接。

我使用 JDK 1.7 和 Windows 7。

在图片中,只有 4 个突出显示的连接是感兴趣的,它们是由客户端创建的。

一个连接 1 用红色标记的条目是服务器端口。

PFA 显示这 4 个连接的图像。!

嗯,我真的很困惑为什么

Selector incomingMessageSelector = Selector.open();

在动态端口上创建连接

【问题讨论】:

  • 这听起来很奇怪。恕我直言,我发现阻塞 NIO 更容易使用,如果您的连接数较少,则速度更快。
  • 是的,它可能从 API 更简单,但我更关注为什么在 TCP 级别创建 4 个连接,而仅从代码创建 1 个连接。
  • 您能否将“端口 50512 和 50513”的条目包括在您的图像中。
  • 我已经更新了图像,因此在新图像中有不同的端口,忘记相应地更新问题文本,我现在也更新了问题

标签: java io nio


【解决方案1】:

图像非常小,但仔细调查后发现

  • 两个 Java 进程
  • 第一个进程与其自身有连接。每端都有一个连接,端口 52209 和 52210。
  • 它还与端口 1001 上的第二个进程建立了连接。
  • 第二个进程是您正在运行的客户端,通过一个连接到端口 1001

【讨论】:

  • 是的,你是对的。但是,我已经关闭了所有 IDE 等并通过记事本运行 :) .. 1 个 java 进程是使用称为套接字测试的工具托管的服务器,另一个 java 进程是我发布的创建客户端连接的代码。当我关闭客户端程序时,我留下了 1 个占用端口 1001(服务器程序)的 java 进程,并且客户端程序创建了套接字级别的连接。
  • 这对我来说很有意义。鉴于表中的两个条目只有一个连接,服务器上的其他条目可以忽略,您能否重新表述问题?
  • 更新了问题,使其更清晰。我想总结一下它共有 5 个 java 进程条目,其中 1 个是服务器,4 个是客户端连接
  • @Sudarshan 你在说哪个进程 ID,因为我只能在一个进程上看到 3 个条目,在另一个进程上看到 1 个。与自身连接的那个与您的代码无关。这为客户端留下一个条目,为服务器留下一个条目。
  • 我有三个进程 id 为 9464 的条目可以吗?,使用普通的 Java Socket API 并创建一个连接,我只得到 1 个条目......我试图理解为什么 NIO 创建超过 1 个套接字连接以及为什么它使用相同的动态端口
【解决方案2】:

1001 和 52211 之间的连接显示了两次,每个方向一次,因为两个端口都是本地端口。

一个选择器可以打开另一个监听套接字,以防它必须处理子选择器,以免超过每个选择器的最大套接字数。

在完成 OP_CONNECT pgphasr 之前,您不应该注册 OP_READ 或 OP_WRITE,此时您还应该取消注册 OP_CONNECT。同时注册这三个肯定是错误的。

【讨论】:

  • “一个选择器可以打开另一个监听套接字,以防它必须处理子选择器,以免超过每个选择器的最大套接字数。” -- 能否请您更详细地向我解释一下... 或者您可以给我一些说明选择器概念如何影响套接字层的文本...
  • 平台对一次可以选择的套接字数量有限制。 Java 没有:它使用子选择器方案,通过额外的套接字与主选择器对话。当子选择器准备就绪时,它会向套接字写入一些内容,以便唤醒主选择器。这是一个实现功能,除了源代码之外,我所知道的任何地方都没有记录。
  • 这是否意味着选择器可以通过其子选择器打开多个套接字?
  • 它将打开与子选择器一样多的套接字,并且它们将在netstat 中显示两次,每个方向一次。
  • 这个场景会创建多少个子选择器?我可以看到每次 Selector incomingMessageSelector = Selector.open();被称为它在动态端口上创建连接为什么会这样?
猜你喜欢
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
相关资源
最近更新 更多