How to determine end of read

199 views Asked by At

I have simple C server and Java client. I'm sending text file line by line from server to client:

    do {
        send(sockfd, line, strlen(line), 0);
        printf("%s\n", line);
    } while ((fgets(line, 100, fp)) != NULL);  

and read it in Java client with:

    Client.getCl().getInputStream().read(inmsg);
    do{             
         decoded = new String(inmsg, "UTF-8");
         System.out.println(decoded);
    }while(Client.getCl().getInputStream().read(inmsg) > 0);  

My problem is that I don't know how to send "end of read" from server to client. The client freezes on last read. I know that methode read() returns integer with number of recieving bytes and -1 when there is nothing to read and 0 when the length of buffer is zero. The only solution which returned -1 to client was to close socket on server side, but I can't use that. Also I've tried following:
1) Send 0 length at the end of sending method to tell client, that length is zero:

send(sockfd, NULL, NULL, 0);  

2) Define flags and send:

#define MSG_FIN 0x200
#define MSG_EOR 0x0080

and again with both flags:

 send(sockfd, NULL, NULL, MSG_FIN);
 send(sockfd, NULL, NULL, MSG_EOR);  

Anyone please help what am I doing wrong here? Thanks

2

There are 2 answers

2
MischaNix On BEST ANSWER

If you want to send intermittent data over the same TCP socket, you'll need to encode the boundaries of the information you're sending within the data you're sending. An example of this is to send "packets" of data with a length-prefix, so that the receiver of a packet will read as many bytes off the socket as the length-prefix says to.

0
Peter Lawrey On

You have two problems with your reader. You assume you will always read a full buffer. You cannot assume this unless you only read one byte at a time. You also assume you will always read whole multi-byte characters, this is unlikely to be true unless you never use multi-byte characters.

Since you are writing text I suggest you send new lines between messages and read the stream as text.

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

This will decode the text, read whole lines and handle any multi-byte characters.