Java 如何确定读取结束

Java 如何确定读取结束,java,c,inputstream,ansi,server-communication,Java,C,Inputstream,Ansi,Server Communication,我有简单的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{

我有简单的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的唯一解决方案是关闭服务器端的套接字,但我不能使用它。我还尝试了以下内容:
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);  

有人请帮忙我做错了什么?谢谢

如果要通过同一TCP套接字发送间歇数据,则需要在发送的数据中对发送的信息的边界进行编码。例如,发送带有长度前缀的“数据包”,这样数据包的接收者将从套接字读取长度前缀所表示的字节数。

您的阅读器有两个问题。您假定总是读取一个完整的缓冲区。除非一次只读取一个字节,否则不能假定这一点。您还假设您将始终读取整个多字节字符,除非您从未使用多字节字符,否则这不太可能是真的

由于您正在编写文本,我建议您在消息之间发送新行,并以文本形式读取流

BufferedReader br = new BufferedReader(new InputStreamReader(
                        Client.getCl().getInputStream(), "UTF-8"));
for(String line; (line = br.readLine()) != null; ) {
    // process a whole line of text at once. e.g.
    System.out.println(line);
}

这将解码文本,读取整行内容并处理任何多字节字符。

我知道您说过您不能使用它,但为什么您不能关闭服务器上的套接字?如果你不愿意关闭它,这不意味着你以后会发送其他东西吗?如果是这样的话,那么Java应该仍然能够读取,对吗?您可能希望提前计算出要发送多少字节,并在数据前面加上该数字,以便客户端可以确定何时停止读取。这与HTTP中的类似。如果您需要通过TCP连接发送不同的“消息”,那么您必须自己实现和处理应用程序级别的问题。TCP并不真正关心这一点。(UDP确实如此,但它的不可靠性可能使其不适合您的用例。即,不是媒体流或P2P。)现在,除非这是学校作业,否则我要做的是获得某种消息传递中间件来处理此问题。我能想到的最简单的跨C和Java的方法可能是。如果您的用例是基于文本的,那么您也可以像HTTP那样做,其中空行表示请求头的结束——当然,您必须确保在发送消息后显式刷新套接字。当客户端接收到一个空行时,它将去做其他事情,然后稍后返回套接字。+1接收器只知道流的结尾。如果你想让它知道“消息”,你需要添加一个协议来做到这一点。e、 g.在每条消息之前发送一个4字节的长度,这样它就知道要读取多少。现在我首先发送多行文件,然后行本身和客户机按照数字所示的次数读取。谢谢