套接字 - C和Java发送之间的差异

时间:2010-12-10 09:55:00

标签: java c sockets nio

我正在将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. Clear Buffer,
  2. 将字符串放入缓冲区,
  3. 放入字符串的大小,
  4. 翻转。
  5. 对于C套接字,即使我有4个单独的send(),所有4个char数组也被一起发送。

    难住了。有任何想法吗?

3 个答案:

答案 0 :(得分:3)

TCP是面向流的协议。也就是说,流分裂的方式无关紧要。因此,需要在特定边界拆分流的设计可能错误地使用TCP。

话虽如此,您可以尝试使用setsockopt选项通过TCP_NODELAY进行“集中”。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

感谢您抽出时间向我提出建议(缓慢的)。我已经尝试启用TCP_NODELAY但它没有解决'问题'。为什么我说“问题” - 回答如下。

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

我非常天真地想要了解ubuntu上的man页面所说的内容。

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的算法。