【发布时间】:2013-12-18 19:23:13
【问题描述】:
我有简单的 C 服务器和 Java 客户端。我正在从服务器到客户端逐行发送文本文件:
do {
send(sockfd, line, strlen(line), 0);
printf("%s\n", line);
} while ((fgets(line, 100, fp)) != NULL);
并在 Java 客户端中读取它:
Client.getCl().getInputStream().read(inmsg);
do{
decoded = new String(inmsg, "UTF-8");
System.out.println(decoded);
}while(Client.getCl().getInputStream().read(inmsg) > 0);
我的问题是我不知道如何将“读取结束”从服务器发送到客户端。客户端在上次读取时冻结。我知道methode read() 返回带有接收字节数的整数,当没有要读取的内容时返回-1,当缓冲区长度为零时返回0。向客户端返回 -1 的唯一解决方案是关闭服务器端的套接字,但我不能使用它。我也试过以下:
1) 在发送方法结束时发送 0 长度告诉客户端,该长度为零:
send(sockfd, NULL, NULL, 0);
2) 定义标志并发送:
#define MSG_FIN 0x200
#define MSG_EOR 0x0080
再次使用两个标志:
send(sockfd, NULL, NULL, MSG_FIN);
send(sockfd, NULL, NULL, MSG_EOR);
任何人请帮助我在这里做错了什么?谢谢
【问题讨论】:
-
我知道你说你不能使用它,但是为什么你不能关闭服务器上的套接字?如果您不愿意关闭它,那是不是意味着您以后要发送其他东西?如果是这样的话,那么 Java 应该仍然可以读取,对吧?
-
您可能需要提前确定要发送多少字节,并在数据前加上该数字,以便客户端可以确定何时停止读取。就像 HTTP 中的
Content-Lengthheader。 -
如果您需要通过 TCP 连接发送不同的“消息”,这是您必须自己实现和处理的应用程序级问题。 TCP 并不真正关心这一点。 (UDP 可以,但它的不可靠性可能使其不适合您的用例。即不适合媒体流或 P2P。)
-
现在,除非这是一项学校作业,否则我要做的是获得某种确实处理此问题的消息传递中间件。我能想到的适用于 C 和 Java 的最简单的可能是 0MQ。如果您的用例是基于文本的,您还可以执行 HTTP 所做的那样,其中空行表示请求标头的结束——您当然必须确保在发送消息后显式刷新套接字。当客户端收到一个空行时,它会去做其他事情,然后再回到套接字。
标签: java c inputstream ansi server-communication