C Board  

Go Back   C Board > General Programming Boards > Networking/Device Communication

Reply
 
LinkBack Thread Tools Display Modes
Old 08-09-2009, 05:50 AM   #1
Registered User
 
Join Date: Dec 2007
Location: France
Posts: 396
Sending image

When i send a text file everything is fine.
When i try to send a .gif it gives me the correct size but goes into a loop and sending the same 11 bytes.

I open the files in binary mode so it cant be the problem.
I got a hunch that it should meet an EOF character or such but i dont check for that so i dont know what could be the problem.

Client sending:
Code:
void Send_File()
{
     //***************************************
     //Read file and send size
     //***************************************
     ifstream file("1.gif", ios::binary);
     char cLength[256] = {0};
     unsigned int nBytesSent = 0, fileSize = 0, r = 0;
     // get length of file:
     file.seekg (0, ios::end); fileSize = file.tellg(); file.seekg (0, ios::beg);
     // allocate memory:
     char * buffer = new char [fileSize];
     // read data as a block:
     file.read (buffer,fileSize);
     file.close();  itoa(fileSize, cLength,10);
     send(inetsock, cLength, strlen(cLength), 0);
     //******************************************
     //Send data
     //******************************************
     char *buf = new char[256];
     cout <<  "fileSize "  <<  fileSize  << endl;  system("pause");
     while(nBytesSent<fileSize)
     {
           string str(buffer); //char* to string

           strcpy(buf, str.substr(nBytesSent, 255).c_str());
           r = send(inetsock, buf, strlen(buf), 0);
           if (r==SOCKET_ERROR)
           {
               cout << "Connection unexpectedly closed \n"; closesocket(inetsock);
           }
           nBytesSent+=r;
           cout << "nBytesSent " << nBytesSent  << endl;

     }
     delete[] buffer; delete[] buf;
}
Server recieving:
Code:
void Recieve_File()
{
   //Recieve size
      char recvBuff[256]={0}; string fileBuff="";
   unsigned int fileSize = 0,    nBytesRecieved = 0,  r = 0;
      recv(AcceptSock, recvBuff, sizeof(recvBuff), 0);
   fileSize=atof(recvBuff);
   //cout << fileSize << endl; system("pause");
   //******************************************
   //Recieve data
   //******************************************
      char *buf = new char[256];
      cout << "fileSize "       << fileSize  << endl;
   while(nBytesRecieved<fileSize)
   {
         memset(buf, 0, 256);
         r=recv(AcceptSock, buf, sizeof(buf), 0);
         fileBuff.append(buf);
         nBytesRecieved+=r+1;
         cout << "nBytesRecieved " << nBytesRecieved  << endl;

   }
   //cout << fileBuff << endl; system("pause");
   ofstream TheCopy("TheCopy.txt",ios::binary | ios::app);
   TheCopy.write (fileBuff.c_str(),fileSize);
   TheCopy.close();
   delete[] buf;
}
__________________
Using Code::Blocks,MingW with Windows.

Last edited by Ducky; 08-09-2009 at 05:57 AM.
Ducky is offline   Reply With Quote
Old 08-09-2009, 06:00 AM   #2
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
There's a lot of strlen() on char arrays which will contain embedded \0 characters.

The whole convert it to a C++ style string, and then back again is a waste of time.

See my previous reply to your other thread on how to send the whole lot in one loop.

Also,
Sending the length in advance is good, but it needs to be a fixed-width record of some sort.
How will you tell say "123" from "12345656"?

It kind of works at the moment because all GIF files begin with "GIF", so working out the end of the number isn't a problem.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 08-09-2009, 06:14 AM   #3
Registered User
 
Join Date: Dec 2007
Location: France
Posts: 396
Ok, thank you Salem, i'll try to implement your code.

"How will you tell say "123" from "12345656"?"

You mean that when i send the size there could be other characters attached to it?
__________________
Using Code::Blocks,MingW with Windows.
Ducky is offline   Reply With Quote
Old 08-09-2009, 06:30 AM   #4
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
Not exactly.
How will you tell the end of the number from the start of the file?

Doing
send(inetsock, cLength, strlen(cLength)+1, 0);
would ensure there was a recognisable delimiter between the length and the file.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 08-09-2009, 07:16 AM   #5
Registered User
 
Join Date: Dec 2007
Location: France
Posts: 396
Ah ok i see it now.

Your code is working like a charm.

Only i still have a problem with images. It gets transfered but it must get corrupted because
there is no image on openning. Though the size is the same.

I didnt change the recieving side maybe there is a function there that mess up things.

This is the sending part edited with your code:
Code:
void Send_File()
{
     //***************************************
     //Read file and send size
     //***************************************
     ifstream file("1.gif", ios::binary);
     char cLength[256] = {0};
     size_t nBytesSent = 0, fileSize = 0, r = 0;
     // get length of file:
     file.seekg (0, ios::end); fileSize = file.tellg(); file.seekg (0, ios::beg);
     char * buffer = new char [fileSize];
     // read data as a block:
     file.read (buffer,fileSize);
     file.close();  itoa(fileSize, cLength,10);
     send(sock, cLength, strlen(cLength)+1, 0);
     //******************************************
     //Send data
     //******************************************
     while ( fileSize )
     {
             int num_sent = send( sock, buffer, fileSize, 0 );
             if ( num_sent > 0 )
             {
                  fileSize -= num_sent;
                  buffer   += num_sent;
             }
     }
     delete[] buffer;
}
__________________
Using Code::Blocks,MingW with Windows.

Last edited by Ducky; 08-09-2009 at 07:19 AM.
Ducky is offline   Reply With Quote
Old 08-09-2009, 08:02 AM   #6
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
> recv(AcceptSock, recvBuff, sizeof(recvBuff), 0);
This probably contains the length, and the first part of the file.

Look at the received length of data.
Extract the file size information, and save the rest to the file.

Storing the received data fragments in a temp array is a waste of effort IMO.
You may as well just save the fragments to a file.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 08-09-2009, 09:28 AM   #7
Registered User
 
Join Date: Dec 2007
Location: France
Posts: 396
> recv(AcceptSock, recvBuff, sizeof(recvBuff), 0);
"This probably contains the length, and the first part of the file."

No, i checked it, it only contains the size.

"Storing the received data fragments in a temp array is a waste of effort IMO.
You may as well just save the fragments to a file."

I just changed this and changed
nBytesRecieved += r+1; to nBytesRecieved += r; and now its working.

Thanks a million Salem!
__________________
Using Code::Blocks,MingW with Windows.

Last edited by Ducky; 08-09-2009 at 12:09 PM.
Ducky is offline   Reply With Quote
Old 08-09-2009, 02:34 PM   #8
Registered User
 
Join Date: Mar 2009
Posts: 71
Quote:
Originally Posted by Salem View Post
There's a lot of strlen() on char arrays which will contain embedded \0 characters.

The whole convert it to a C++ style string, and then back again is a waste of time.

See my previous reply to your other thread on how to send the whole lot in one loop.

Also,
Sending the length in advance is good, but it needs to be a fixed-width record of some sort.
How will you tell say "123" from "12345656"?

It kind of works at the moment because all GIF files begin with "GIF", so working out the end of the number isn't a problem.
For the fixed length thing, just do what I do.

string bob = "%57092370$";
string number = bob.substr(bob.find("%",0),bob.find("$",0)-bob.find("%",0));

Then just convert number to an int and your good!
azjherben is offline   Reply With Quote
Old 08-10-2009, 01:17 AM   #9
Registered User
 
Join Date: Dec 2007
Location: France
Posts: 396
Thank you Azjherben!

But how would you know what the delimiter characters would be?

By the way any idea why is this working perfectly on one computer but when i put them on a lan its not.

On the sender side all data are sent. At least thats what the cout<< says that i put in the loop.

On the reciever side, first it recieves the right number of bytes to recieve but then it gets nothing.

If i give the command to send it again it will recieve the command itself, the number of bytes to send and the data too but all within the number of bytes to send so the end of the data
isnt there anymore, because the command itself and the number of bytes to send takes up about 4 bytes in the beginning.
__________________
Using Code::Blocks,MingW with Windows.

Last edited by Ducky; 08-10-2009 at 05:02 AM.
Ducky is offline   Reply With Quote
Old 08-10-2009, 02:24 AM   #10
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
> But how would you know what the delimiter characters would be?
Anything you like, so long as you can identify it as being a delimiter, and not part of the first block of data, and not part of the 2nd block of data.

You treat the data as a byte stream.
Finite-state machine - Wikipedia, the free encyclopedia
For each byte, you should be able to specify exactly 1 state or 1 transition, like
- isLengthChar
- isDelimiter
- isImageChar
If you can't uniquely identify where you are, then your protocol is broken.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 08-10-2009, 07:20 AM   #11
Registered User
 
Join Date: Dec 2007
Location: France
Posts: 396
Are you saying to have just one recv() on the recieving size and then separating the file size from the data?

Yes this is good when you know what will be the data.

But when the data starts with a number, how would you know what number is the size of the file and what is the data?

By the way i changed the recieving side of the code just like you showed me on the sending side.

Now when i dont send the size (i compile the size in it) its working.
When i send the size of the file it looks like after the first recv() function got the size it continues waiting and not passing on to the next recv() function.
__________________
Using Code::Blocks,MingW with Windows.
Ducky is offline   Reply With Quote
Old 08-10-2009, 09:15 AM   #12
Registered User
 
Join Date: Mar 2009
Posts: 71
Quote:
Originally Posted by Ducky View Post
Thank you Azjherben!

But how would you know what the delimiter characters would be?

By the way any idea why is this working perfectly on one computer but when i put them on a lan its not.

On the sender side all data are sent. At least thats what the cout<< says that i put in the loop.

On the reciever side, first it recieves the right number of bytes to recieve but then it gets nothing.

If i give the command to send it again it will recieve the command itself, the number of bytes to send and the data too but all within the number of bytes to send so the end of the data
isnt there anymore, because the command itself and the number of bytes to send takes up about 4 bytes in the beginning.


I had a simular problem.
Becuase, I made a program just like this one, it recived it correctly, except it added a few extra characters to the end of the new file.

I'll go find that code now.
azjherben is offline   Reply With Quote
Old 08-10-2009, 09:28 AM   #13
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
> Are you saying to have just one recv() on the recieving size and then separating the file size from the data?
You can't rely on the fact that if you send say 6 bytes that you will ALWAYS receive those 6 bytes (by themselves) in a single recv call.

TCP only sees the stream, and delivers the stream in order.
How individual packets arrive is completely arbitrary.

It's YOUR job to sort out the stream of bytes into something meaningful, and one way to do that is to send recognisable delimiters.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 08-10-2009, 09:42 AM   #14
Registered User
 
Join Date: Dec 2007
Location: France
Posts: 396
If its so then whats the point in sending the size of the file?

And btw isnt send(sock, cLength, strlen(cLength)+1, 0); suppose to send it in the 3 argument?

And why would it work perfectly on one computer (im using 192.168.1.2 not 127.0.0.1), even for bigger files?


@azjherben

You intrigue me. Im interested.
__________________
Using Code::Blocks,MingW with Windows.
Ducky is offline   Reply With Quote
Old 08-10-2009, 11:46 AM   #15
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
> If its so then whats the point in sending the size of the file?
Well if you're only sending just the one file, probably not a lot.

But if you were browsing a web page for example, then multiple things would need to be sent.


> And btw isnt send(sock, cLength, strlen(cLength)+1, 0); suppose to send it in the 3 argument?
Huh?
With just strlen(), then "123\0" would be sent as "123"
Adding 1 means "123\0" gets sent (a useful delimiter in it's own right)
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem reading tiff image files? compz C++ Programming 9 10-30-2009 04:17 AM
file won't close despite calling the function TiffClose(image) caggles C Programming 1 05-27-2009 12:46 PM
Simple Image Processing ejohns85 C++ Programming 4 03-19-2009 12:10 PM
Image rotation - doesn't always work ulillillia C Programming 12 05-03-2007 12:46 PM
C++ Image Processing Homework (dynamic 2d array binary i/o trouble) Xixchil C++ Programming 4 03-02-2003 09:12 AM


All times are GMT -6. The time now is 09:32 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22