如何确定阅读结束

时间:2013-12-18 19:23:14

标签: 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{             
         decoded = new String(inmsg, "UTF-8");
         System.out.println(decoded);
    }while(Client.getCl().getInputStream().read(inmsg) > 0);  

我的问题是我不知道如何从服务器向客户端发送“读取结束”。客户端在上次读取时冻结。我知道,方法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);  

任何人请帮助我在这里做错了什么?感谢

2 个答案:

答案 0 :(得分:5)

如果要通过同一TCP套接字发送间歇性数据,则需要对要发送的数据中发送的信息的边界进行编码。这种情况的一个例子是发送带有长度前缀的数据“数据包”,这样数据包的接收者就可以读取套接字的长度字符所说的字节数。

答案 1 :(得分:0)

您的读者遇到两个问题。您假设您将始终读取完整缓冲区。除非您一次只读取一个字节,否则不能假设这一点。您还假设您将始终读取整个多字节字符,除非您从不使用多字节字符,否则这不太可能。

由于您正在编写文本,我建议您在消息之间发送新行并将文本作为文本读取。

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);
}

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