2013-12-18 30 views
3

我有简单的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

我知道你说过你不能使用它,但_why_不能关闭服务器上的套接字吗?如果你不愿意关闭它,那不是说你以后会发送其他东西吗?如果是这样的话,那么Java应该仍然可以阅读,对吧? –

+0

您可能需要提前计算出要发送的字节数,并将数据前缀为该数字,以便客户端可以确定何时停止阅读。它就像HTTP中的['Content-Length'头部](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13)。 –

+0

如果您需要通过TCP连接发送不同的“消息”,那么您需要实施和处理自己的应用程序级别的问题。 TCP并不关心这一点。 (虽然UDP不可靠,但它的不可靠性可能使它不适合你的使用情况,即不是媒体流或P2P) – millimoose

回答

5

如果要通过同一个TCP套接字发送间歇性数据,则需要对要发送的数据中发送的信息的边界进行编码。一个例子是发送带有长度前缀的“数据包”,这样一个数据包的接收方将读取长度前缀所指的套接字数量。

+0

+1 reciver知道的唯一事情就是流的结束。如果你想知道“消息”,你需要添加一个协议来做到这一点。例如在每条消息前发送一个4字节的长度,以便知道要读多少。 –

+0

现在我首先发送多行文件,然后将自己和客户端读取的次数与数字所说的次数相同。谢谢 –

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

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