我正在将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的伪代码。
对于C套接字,即使我有4个单独的send(),所有4个char数组也被一起发送。
难住了。有任何想法吗?
答案 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的算法。