【问题标题】:Why java.nio.SocketChannel not send data (Jdiameter)?为什么 java.nio.SocketChannel 不发送数据(Jdiameter)?
【发布时间】:2014-03-18 11:35:27
【问题描述】:

我创建了简单的直径客户端和服务器 (Link to sources)。客户端必须发送 10000 条 ccr 消息,但在 wireshark 中我看到只会发送约 300 条 ccr 消息。其他消息在客户端引发超时。我在装有 Windows 7 的不同计算机上运行服务器和客户端。我在 JDiameter 源代码 line where jdiameter sended ccr (line 280) 中找到了,我认为如果套接字的发送缓冲区已满,ccr 未发送。我在第 280 行之前添加了这段代码

while(bytes.hasRemaining())

客户端发送 ~9900 ccr,但速度很慢。我在用 c++ 编写的其他直径服务器上测试客户端,客户端(在 jdiameter 上没有我的更改)发送 ~7000 ccr,但此服务器托管在 debian 上。

我不知道如何解决这个问题,感谢您的帮助。

【问题讨论】:

    标签: java sockets mobicents restcomm diameter-protocol


    【解决方案1】:

    如果发送方的发送返回零,则表示发送方的套接字发送缓冲区已满,进而表示接收方的套接字接收缓冲区已满,进而表示接收方读取的速度比发送方发送的速度慢。

    所以加快接收器的速度。

    NB 在非阻塞模式下,仅在 write() 调用返回零时循环是不够的。如果write() 返回零,您必须:

    1. OP_READ 取消注册频道并为OP_WRITE 注册它
    2. 返回选择循环。
    3. OP_WRITE 触发时,再次写入。这一次,如果它没有返回零,请注销OP_WRITE,并(可能根据您的要求)注册OP_READ

    请注意,始终保持为OP_WRITE 注册的频道也不正确。套接字通道几乎总是可写的,这意味着套接字发送缓冲区中几乎总是有空间。您感兴趣的是 not-可写和可写之间的转换

    【讨论】:

    • 我在 TcpTransportClient.initialize 中将接收和发送套接字缓冲区增加到 1mb:socketChannel.socket().setReceiveBufferSize(size); socketChannel.socket().setSendBufferSize(大小);并将此代码添加到 sendMessage: rc = socketChannel.write(bytes); if (rc == 0) while (bytes.hasRemaining()) { Thread.sleep(10l); rc = socketChannel.write(bytes);在 debian 上的 c++ 上使用直径服务器可以正常工作,但在 jdiameter 服务器上的问题没有解决。
    • @MadCrank 提高缓冲区大小不会加快接收器的速度,它实际上只会推迟问题。您还没有发布您的源代码,但我在您的链接中找到的while (bytes.hasRemaining())while (rc < bytes.array().length) 都不是用 NIO 编写的正确方法。
    • 是否需要注销OP_READ?
    • @mike 这不是必要的, 但是如果您不能写入旧数据,则读取新数据没有多大意义。让对端停止,而不是尝试读取他发送给您的所有新内容,填满您自己的读取缓冲区等。
    猜你喜欢
    • 2017-01-05
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 2021-02-11
    • 2018-12-10
    • 2012-05-19
    • 2015-05-15
    • 1970-01-01
    相关资源
    最近更新 更多