【问题标题】:Sockets - Difference between C and Java sending套接字 - C 和 Java 发送之间的区别
【发布时间】:2010-12-10 09:54:59
【问题描述】:

我正在将 Java 应用程序(使用 NIO)转换为 C 套接字,但遇到了问题。同时,我正在使用grinder,作为TCPProxy,查看传输了什么。

我有 4 行需要作为握手的一部分发送给客户端。

Hello~Server\r\n
Hello1~Server1\r\n
Hello2~Server2\r\n
Hello3~Server3\r\n

对于 Java 应用程序(使用 NIO),每个字符串在每个 Java NIO flip() 之后发送。就是说上面的4行一次发出一个。

我有以下 Java 伪代码。

  1. 清除缓冲区,
  2. 将字符串放入Buffer,
  3. 放置字符串的大小,
  4. 翻转。

对于 C 套接字,即使我有 4 个单独的 send(),所有 4 个字符数组也会一起发送出去。

难住了。有任何想法吗?

【问题讨论】:

  • 您是否关闭了 nagle 和所有合并?
  • 嘿彼得。我正在阅读有关 nagle 的信息,但我还没有将其关闭。我会尝试的。谢谢老兄

标签: java c sockets nio


【解决方案1】:

TCP 是一种面向流的协议。也就是说,流如何拆分应该无关紧要。因此,需要在特定边界拆分流的设计可能错误地使用了 TCP。

话虽如此,您可以尝试通过setsockopt 使用TCP_NODELAY 选项来关闭“集总”。

【讨论】:

    【解决方案2】:

    您的 C 代码发送的消息可能被 Nagle's algorithm 合并为一个数据包。您可以通过套接字上的setting the TCP_NODELAY option 禁用此功能 禁用 Nagle 算法。但是,您应该记住 TCP 不需要尊重您的消息边界,因此您的协议应该有自己的方式来确定何时收到完整的消息,而不是依赖于 send() 和recv() 在端点调用。

    【讨论】:

    • 吉姆,感谢您的提醒。我会记住你的话。再次感谢您的快速回复!说到这里,有没有人知道 Java nio 是否禁用了 Nagle 的算法?
    【解决方案3】:

    感谢您抽出宝贵时间给我建议(慢的)。我试过启用 TCP_NODELAY 但它没有解决“问题”。为什么我说“问题” - 请在下面回答。

    我查看了我的 send() 并注意到我使用了 sizeof(message) 而不是 strlen(message)。 sizeof() - 获取要发送的字节大小。 strlen() - 获取要发送的字符数,不包括 \0。

    我很天真地遵循了 ubuntu 上的手册页所说的内容。

    yakult121$man 发送

    ssize_t send(int sockfd, const void *buffer, size_t len, int flags);

    我认为参数 size_t len 是为了使用 sizeof(),就像我将它用于 memset() 一样。

    yakult121$man memset

    void *memset(void *s, int c, size_t n);

    我也终于明白 socklen_t 和 size_t 是不同的数据类型了。

    再次感谢大家。我无法找到问题所在,并会继续指责 Nagle 的算法。

    【讨论】:

    • 实际上sizeof 是一个编译时的东西:它计算表达式或类型占用的字符数。当你需要产生size_t 类型的东西时,自动使用sizeof - 你需要考虑你想做什么。
    猜你喜欢
    • 2020-10-18
    • 2013-05-21
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 2012-01-26
    相关资源
    最近更新 更多