![]() |
| | #1 |
| Registered User Join Date: Dec 2007 Location: France
Posts: 396
| Sending image 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;
}
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 | |
| | #2 |
| and the hat of vanishing 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 | |
| | #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 | |
| | #4 |
| and the hat of vanishing 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 | |
| | #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 | |
| | #6 |
| and the hat of vanishing 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 | |
| | #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 | |
| | #8 | |
| Registered User Join Date: Mar 2009
Posts: 71
| Quote:
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 | |
| | #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 | |
| | #10 |
| and the hat of vanishing 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 | |
| | #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 | |
| | #12 | |
| Registered User Join Date: Mar 2009
Posts: 71
| Quote:
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 | |
| | #13 |
| and the hat of vanishing 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 | |
| | #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 | |
| | #15 |
| and the hat of vanishing 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 | |
![]() |
| Thread Tools | |
| Display Modes | |
|
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 |