views:

92

answers:

2

I have created small socket programs (client/server). Client will transfer all formats of files to server.The problem i am facing now is - I read mp3 file in binary mode and sent to the server. Server reads the content from the buffer and create a file.But when i am trying to open the file, it not getting open. But size remains same as original one. Can anyone point where i am doing wrong. Here is my Server side code:

    recv(newSocket,fileSize,50,0); //Receiving file size

//  buffer=malloc(atoi(fileSize));
    int i=0;

    recv(newSocket,buffer,atoi(fileSize),0);
    fwrite(buffer,1,atoi(fileSize),out);

Client side: fread(data,1,lSize,file);

    sprintf(temp,"%ld",lSize);

    send(socketDes,temp,strlen(temp),0);


    send(socketDes,data,strlen(data),0);
A: 

Trying to open the file how, with an MP3 player after it has been transmitted?

Perhaps you're not writing the output file in "binary" mode; on some operating systems this will cause bytes to be translated, trashing the file if it really is binary and not text.

If you're opening the file for write using fopen(), include a "b" in the second argument:

FILE *out = fopen("incoming.mp3", "wb");
unwind
Here is my code for ur ref:
Winbros
+4  A: 

It might be that, when reading from a stream-based socket, you are not getting all the bytes you think you are getting. Then you are writing a file of the correct size, but only the beginning of the file will have any meaningful data.

If you are using TCP (a stream-oriented connection), when you go to read from the socket into a buffer (you are probably using a byte/char array), you will only get all the bytes which are available at the time of the call. The call to the reading function will return immediately but the buffer into which the data is written will only be partially full.

To fix this, you will need to check how many bytes were actually read from the socket (usually the reading call will return that number), and then repeatedly read from the socket until you have all the bytes you need.

Update

With regards to your code, it certainly looks like you only make one call to recv() and do not check to make sure the entire file was transferred. You will need to put this in a loop and continuously read data until you have read as much as you want to (in this case, the size of the entire file).

You may also want to fix this problem on the sending side. Even though you have the sleep command between calls to send, send will only send a certain amount of data per call. You will need to place send in a loop and keep sending data until you have sent all the data you wish to send.

Consider the following (untested pseudo-)code for recv:

int numberOfReceivedBytes=0;
while (numberOfReceivedBytes<fileSize){
    numberOfReceivedBytes+=recv(newSocket,buffer + numberOfReceivedBytes,sizeof(*buffer),0)
}

Furthermore, it looks like when you read the file size from the socket, you may accidentally get part of the file itself in addition to the size of the file. Make sure you know exactly how many bytes will indicate the actual size of the file and read only that many bytes. Also, atoi only works for the string (ASCII) representation of a number. Your server is receiving the actual number.

To do sending:

int numberOfSentBytes=0;
while (numberOfSentBytes<fileSize){
    numberOfSentBytes+=send(newSocket,buffer+numberOfSentBytes,fileSize-numberOfSentBytes+1,0);
}
Jack
Ok thank you let me try and let you know
Winbros
Can you please let me know how to send and recv in loop in ref to my code. Since i am read entire file content into data in one go. i am not sure how to split and send. Can you please help in this regards
Winbros
You can usually read the entire file in one go (though I wouldn't count on that--you might want to put that in a loop too). I edited my answer to show an example of sending in a loop.
Jack
Just a notice why you need to check the actual number of read/written bytes: Certain I/O operations can be interrupted, which means you have to redo them again if that happens (you check this by checking the return value). This is also a good reason for splitting up the transfers in smaller chunks, or you will pretty much never finish transferring a large file.
gablin
Thanks to all for helping me out. I got the o/p.
Winbros