Thread: Trouble with sending binary data

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    9

    Question Trouble with sending binary data

    Hi all. Thanks ahead for reading this, heres the background
    I've been trying to make a simple peer-to-peer and I'm stuck at the very last part of this. Now don't get me wrong, I'm in 3rd year univ, and we've been working on this for 3 days, about 8 hrs each day (Just the part I'm about to explain now) and the teacher assitant can't help either.

    ::: (coding in linux)

    Code:
    void processFile(char *file,int peerfd){
    	char buf[1];
    	int fd;
    
    	printf("Filename is %s\n",file);
    	
    	if ((fd=open(file,O_RDONLY)) ==-1){
    		fprintf(stdout,"Usage Error: File does not exist\n");
    		exit(1);
    	}
    	else{
    		while(read(fd,buf,sizeof(buf))!=0){
    			write(peerfd,buf,sizeof(buf));
    			printf("r");
    		}
    	close(fd);	
    	}

    Where peerfd is the file descripter that is made , connected to the other peer. The problem is, once we run it and send a file (file exists etc) , hit hangs, so we hit cntrl-c to terminate it, and only then it displays on the peer window (file received). So we fix this by typing close(peerfd), but doing this makes pictures send fine, but txt files only get sent 1byte (notice the size of buff)

    Edit:
    I talked to the TA, it seems that the peer is expecting some symbol, or some flag that says "OK the file is finished sending". See I'm testing this against a client that I know works, but we're not aloud to look at it . So when I close the file descriptor myself, by saying close (fdpeer), it gives me
    read from peer: Connection reset by peer
    Which means the peer is still expecting data (even though I finished sending) and its what I would call a brutal disconnection.

    Thanks!!!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Mcmaxx View Post
    Code:
    		while(read(fd,buf,sizeof(buf))!=0){
    			write(peerfd,buf,sizeof(buf));
    			printf("r");
    		}
    This isn't correct. Unless the file is exactly a multiple of sizeof(buf) bytes in length, the last pass through this loop will send extra garbage bytes. Also, the condition should be "> 0" not "!= 0". If read() fails, it returns -1, this -1 is not equal to zero, so you keep looping. The next read will also fail, so you loop infinitely while pumping garbage to the peer. Thirdly, the write() may not write all the bytes. You need to keep writing bytes until they are all successfully written.

    So when you call read(), get the REAL number of bytes read. Then call write() in a loop (so, a loop inside a loop) which keeps writing until all of those bytes have been sent.

    Where peerfd is the file descripter that is made , connected to the other peer. The problem is, once we run it and send a file (file exists etc) , hit hangs, so we hit cntrl-c to terminate it, and only then it displays on the peer window (file received).
    This is probably due to not sending the correct "end of transmission" symbol, whatever it is. When the program exits, the connection is closed, the peer gets a disconnect, and it bumps out of its I/O loop.

    So we fix this by typing close(peerfd), but doing this makes pictures send fine, but txt files only get sent 1byte (notice the size of buff)
    Probably because you aren't checking anywhere how many bytes are actually read and written.

    I talked to the TA, it seems that the peer is expecting some symbol, or some flag that says "OK the file is finished sending".
    Well, you're going to have to know what that symbol is, then!

    EDIT: And for the love of Dog, make that buffer bigger! Unlike the stdio library, UNIX I/O functions are NOT buffered which means you are making two system calls for every single byte processed. Yuck!
    Last edited by brewbuck; 04-11-2007 at 04:36 PM.

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I think I would start by checking return values for read() and write(). Your test condition for read() assumes that a non-zero value means data was read, but it could also mean the return value was -1 due to an error.
    If you understand what you're doing, you're not learning anything.

  4. #4
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by brewbuck
    This isn't correct. Unless the file is exactly a multiple of sizeof(buf) bytes in length, the last pass through this loop will send extra garbage bytes.
    Since sizeof(buf) is 1, the file will always be an exact mutliple of sizeof(buf).
    If you understand what you're doing, you're not learning anything.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    > Unless the file is exactly a multiple of sizeof(buf) bytes in length
    Since buf has one element, this is highly likely.

    [edit] Too slow; wow, this thread is popular. [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by itsme86 View Post
    Since sizeof(buf) is 1, the file will always be an exact mutliple of sizeof(buf).
    That's only true until someone changes it. And I guarantee that the person who changes it will do so late at night, while drunk, three hours before they fly to another continent for 3 weeks with no way of contacting them :-)

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    Thanks for the fast replies!!


    So the problem is not the extra garbage, because of the buffer size that I specified.

    I can do the error checking, >0 and whatnot, and if -1 an error occurs. But say an error DID occur. I somehow have to tell the peer that I'm finished sending. Ok, fair enough. Lets say an error does occur i force the file descriptor to close, nothing I can do about it.

    But I am sending it one byte at a time, so therefore, I am writing one byte at a time. And it's not sending that very last byte that is supposed to let the other side terminate the connection.

    Thanks again!

    That's only true until someone changes it. And I guarantee that the person who changes it will do so late at night, while drunk, three hours before they fly to another continent for 3 weeks with no way of contacting them :-)
    Assume no one will be touching my code after I get it to run... thanks!

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Assume no one will be touching my code after I get it to run...
    Never make assumptions.

    I can do the error checking, >0 and whatnot, and if -1 an error occurs. But say an error DID occur. I somehow have to tell the peer that I'm finished sending. Ok, fair enough. Lets say an error does occur i force the file descriptor to close, nothing I can do about it.
    If a really bad error occurs, there's no way you'd be able to send a "transmission finished" character sequence to the peer. It should have a timeout; if it get no data within ten seconds, it gives up and assumes that something went wrong.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Mcmaxx View Post
    But I am sending it one byte at a time, so therefore, I am writing one byte at a time. And it's not sending that very last byte that is supposed to let the other side terminate the connection.
    Well, how could it send it? You haven't written that part! Surely the assigment explains what this termination symbol is, right? So send it when the transmission is finished, either normally OR because of an error.

  10. #10
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    Quote Originally Posted by dwks View Post
    Never make assumptions.
    I appreciate the concern but for something that has been causing us over 24 hours of problems, I will deal with that after.

    I edited the code

    Code:
    if ((fd=open(file,O_RDONLY)) ==-1){
    		fprintf(stdout,"Usage Error: File does not exist\n");
    		exit(1);
    	}
    	else{
    		while((i=read(fd,buf,sizeof(buf)))!=0){
    			write(peerfd,buf,sizeof(buf));
    			printf("r");
    			if (i<0){
    				fprintf(stderr,"Error occured reading file");
    				close(peerfd);
    			}	
    
    		}
    	close(fd);	
    	}
    For the simple error checking.

    If any suggestions arise, please tell me.

    One thing I found out is I'm reading until =0, and then I stop reading, but what if because of that , I miss out the final byte that lets the FD know its terminated?
    Thanks

  11. #11
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    Quote Originally Posted by brewbuck View Post
    Well, how could it send it? You haven't written that part! Surely the assigment explains what this termination symbol is, right? So send it when the transmission is finished, either normally OR because of an error.
    Thanks for the reply


    Code:
    write(peerfd,buf,sizeof(buf));
    I did write the code, it's writing back to the file descriptor of the other client. The client is reading the data , successfully(since it sends all of it except that very last byte)

    I have an idea, but I think its cheating::


    Since I'm testing this with the profs client, maybe the prof has some statement in his I/O loop that says "if this byte == /n, stop reading, terminate connection".. and maybe THIS is why I can't figure out what the termination byte is.


    This again is cheating, and he didn't provide any help on this matter. We've emailed him and posted it on his forums, but he seems to be the type to not give 2nd thoughts to the problem.

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    while((i=read(fd,buf,sizeof(buf)))!=0){
    Also, the condition should be "> 0" not "!= 0". If read() fails, it returns -1, this -1 is not equal to zero, so you keep looping. The next read will also fail, so you loop infinitely while pumping garbage to the peer.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #13
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    Quote Originally Posted by dwks View Post
    Code:
    while((i=read(fd,buf,sizeof(buf)))!=0){
    I implemented it in the revised code

    Code:
    if (i<0){
    fprintf(stderr,"Error occured reading file");
    close(peerfd);
    break;
    }
    I just added the break; now, but the FD connected to the peer is terminated, the FD from reading the file is terminated outside the while loop, and it breaks the while loop (break

    Thanks for the reply!! I'm so relieved at least I'm getting some progress

  14. #14
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    Hey guys


    I'm thinking forget this complicated guessing and checking, I'll leave that for my real job

    I'm just going to read and send until I have no more data, and then receive and write until I get no more data.

    Screw the prof and his bs

  15. #15
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    You never even tried:
    Code:
    if(write(peerfd,buf,sizeof(buf)) < sizeof(buf))
      // something's wrong
    You implemented error checking for read(), but not write(). Don't give up so fast.
    If you understand what you're doing, you're not learning anything.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Trouble with binary tree
    By dra in forum C++ Programming
    Replies: 4
    Last Post: 05-29-2009, 05:53 PM
  2. sending data over UDP from serial port
    By forumguy in forum Linux Programming
    Replies: 0
    Last Post: 04-25-2009, 02:10 PM
  3. Sending data - line by line?
    By tuckker in forum C Programming
    Replies: 0
    Last Post: 02-21-2009, 09:31 PM
  4. Changing header data in binary file
    By neruocomp in forum C Programming
    Replies: 8
    Last Post: 11-14-2008, 07:30 PM
  5. Binary comparison
    By tao in forum Windows Programming
    Replies: 0
    Last Post: 06-28-2006, 12:10 PM