0

我已经实现了一个 C 服务器和一个 Java 客户端,它们通过 TCP 相互通信。问题是当客户端发送一个字符串时,C 服务器中的 recv() 调用只是读取一个字符并立即返回。如果我在 recv() 处设置断点,然后进行单步处理,服务器会收到发送的整个字符串。这是我在 C 中使用的 recv 调用

char tempBuffer[256] = {'\0'};  
int retVal = recv(hClientSocket, tempBuffer, sizeof(tempBuffer), 0);

这是Java客户端。

clientSocket = new Socket("127.0.0.1", 24886);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes("alert(\"hi\")");

我的问题是,有没有一种方法可以让我完成这项工作,而不必在我的 C 服务器代码中放置一个 while 循环来分别接收每个字符?最好的方法是什么?我实现了这里给出的 C++ 客户端,它工作正常。所以我猜这是Java+C++互操作性的一些问题。谢谢!

4

4 回答 4

4

尽管 Scott M 所说的在 Java 方面是正确的(关于使用flush),但您将不得不重新设计整个通信协议。

您将不得不告诉 C 代码,预计要发送多少字节(这将是最容易跟踪的),或者使用某种终止字符来识别字符串输入已经结束(例如空终止符字节)。

绝对不能保证网络层不会任意切断转换,因此请防御性地编写代码并期望recv始终接收部分数据,您必须组装这些数据以供内部使用。

于 2012-04-13T12:45:09.167 回答
2

尝试刷新 java 流。它们通常是缓冲的,这将导致将字节写入流的一些延迟。足够长以全速搞乱代码,足够短以在调试时发送整个字符串。

于 2012-04-13T12:37:19.997 回答
2

使用 TCP 没有办法解决“放置一个 while 循环recv()”。TCP 是建立在有限大小的数据包服务 (IP) 之上的流协议。TCP 自己进行“打包”,而且实际上非常聪明。这意味着您永远不知道从套接字读取的下一次将返回多少字节。

众所周知的有效策略是设计您的应用程序级协议,以便消息本身告诉它有多大,然后循环读取,直到您有完整的消息要处理。

话虽如此,假设您知道预期的数据量,您可以使用它来等待给定数量的数据,即调用MSG_WAITALL标志。recv(2)

于 2012-04-13T12:45:09.067 回答
1

我曾经尝试过使用一个标头来指示字符串的长度..这样 din 必须检查消息的结尾..

于 2012-04-13T12:42:24.920 回答