6 Replies - 591 Views - Last Post: 17 September 2011 - 12:51 AM Rate Topic: -----

#1 James_Alex  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 156
  • Joined: 21-August 09

Transferring file problem

Posted 15 September 2011 - 02:58 PM

hello, like the title says, i have a probleme in transfering a file from a client to a server

Client sending code
void CClient::Upload(char *szFile)
{
	FILE *pFile = fopen(szFile, "rb");
	char szBuffer[1000];
	int iReaded = fread(szBuffer, sizeof(char), 1000, pFile);
	szBuffer[iReaded] = '\0'; 
	while(iReaded > 0)
	{
		// Prepare the packet
		stPacket packet;
		packet.packetType = PACKET_TYPE_DOWNLOADING;
		packet.iClientID = m_iClientID;
		strcpy(packet.szBuffer, szBuffer);
		// Send the packet
		GetSocket()->Send((const char *)&packet, sizeof(packet), NULL, -1);
		printf("Readed: %d\n", iReaded);
		// Read the next buffer
		iReaded = fread(szBuffer, sizeof(char), 1000, pFile);
		szBuffer[iReaded] = '\0'; 
		printf("new read %d\n", iReaded);
	}
	// Prepare the finish packet
	stPacket packet;
	packet.packetType = PACKET_TYPE_DOWNLOAD_FINISH;
	packet.iClientID = m_iClientID;
	// Send the packet
	GetSocket()->Send((const char *)&packet, sizeof(packet), NULL, -1);
}



My packet structure
struct stPacket
{
	int			iClientID;			// Client id who sended the packet
	ePacketType	packetType;			// Type of packet that
	// **** files informations **** //
	int			iFilesCount;		// Number of files sended
	char		szFile[100][512];	// Files names
	// **** functions variables(Reserved) **** //
	char		szBuffer[1000];		// buffer used for functions calling or file transferring
};



Server receiving code

void CServer::StartDownload(char *szFile)
{
	m_pFile = fopen(szFile, "wb");
	if(!m_pFile)
		return;

	m_bDownloading = true;
}

void CServer::Download(char *szBuffer)
{
	if(!m_bDownloading)
		return;

	fputs(szBuffer, m_pFile);
}

void CServer::EndDownload()
{
	fclose(m_pFile);
	m_bDownloading = false;
}



the CServer::Download is called every time the downloading packet is received and the szBuffer is the buffer sended
My socket is SOCK_DGRAM(no connect neither accept functions are called) and its using UDP port(i know its recommended to use TCP but i want to use SOCK_DGRAM wich dosent support TCP port connections)

the probleme is that when i start sending the file i got that
Readed 1000
Next Read 1000
Readed 1000
Next Read 1000
...
Readed 756
Next Read 0


then the client window crashs saying "Run time check Failure #3: the Stack around 'szBuffer' was corrupted"
i dont see anything wrong with my code

also when the download is finished, it dosent send the whole file, i mean im trying to send a picture with the size of 111 Kb and i got only a picture with a ~3 kb, whats the probleme with my code ?

thanks in advance :)

Is This A Good Question/Topic? 0
  • +

Replies To: Transferring file problem

#2 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1327
  • View blog
  • Posts: 4,554
  • Joined: 19-February 09

Re: Transferring file problem

Posted 15 September 2011 - 06:28 PM

Here the buffer is of size 1000, so if you read 1000 bytes szBuffer[iReaded] will be szBuffer[1000] which is out of bounds.

	char szBuffer[1000];
	int iReaded = fread(szBuffer, sizeof(char), 1000, pFile);
	szBuffer[iReaded] = '\0'; 



A binary file will commonly hold bytes that are of value 0, so using strcpy() is liable only to copy some of the buffer.

strcpy(packet.szBuffer, szBuffer);


Was This Post Helpful? 2
  • +
  • -

#3 James_Alex  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 156
  • Joined: 21-August 09

Re: Transferring file problem

Posted 16 September 2011 - 01:21 AM

View Post#define, on 16 September 2011 - 02:28 AM, said:

Here the buffer is of size 1000, so if you read 1000 bytes szBuffer[iReaded] will be szBuffer[1000] which is out of bounds.

	char szBuffer[1000];
	int iReaded = fread(szBuffer, sizeof(char), 1000, pFile);
	szBuffer[iReaded] = '\0'; 



A binary file will commonly hold bytes that are of value 0, so using strcpy() is liable only to copy some of the buffer.

strcpy(packet.szBuffer, szBuffer);



thanks for the help, i fixed the client crashing probleme
but still cannot send the whole 111 kb pic, it only sends ~3 kb

void CClient::Upload(char *szFile)
{
	// Prepare our packet
	stPacket packet;
	packet.iClientID = m_iClientID;
	// Open the file
	FILE *pFile = fopen(szFile, "rb");
	if(!pFile)
		return;
	// Set the file pos to the end
	fseek(pFile, 0, SEEK_END);
	// Get the file size
	int iSize = ftell(pFile);
	// Set the file back to the beginning
	fseek(pFile, 0, SEEK_SET);
	// Read 1000 bytes from the file
	int iReaded = fread(packet.szBuffer, sizeof(char), 1000, pFile);
	packet.szBuffer[iReaded-1] = '\0'; 
	int iTotal = iReaded;
	// Loop until the file reading is finished
	while(iReaded > 0)
	{
		// Setup the packet type
		packet.packetType = PACKET_TYPE_DOWNLOADING;
		// Send the packet
		GetSocket()->Send((const char *)&packet, sizeof(packet), NULL, -1);
		printf("Readed: %d\n", iReaded);
		// Read the next buffer
		iReaded = fread(packet.szBuffer, sizeof(char), 1000, pFile);
		if(iReaded > 0)
			packet.szBuffer[iReaded-1] = '\0'; 
		printf("new read %d\n", iReaded);
		iTotal += iReaded;
	}
	printf("finished reading (readed: %d - size: %d) %s\n", iTotal, iSize, iTotal != iSize ? "reading fail" : "reading succeeded");
	// Prepare the finish packet
	packet.packetType = PACKET_TYPE_DOWNLOAD_FINISH;
	// Send the packet
	GetSocket()->Send((const char *)&packet, sizeof(packet), NULL, -1);
}



Output
Readed 1000
new read 1000
.....
Readed 771
new read 0
finsihed reading (readed: 20771 - size: 20771) reading succeeded



so the file reading is done correctly, but sending or receiving is corrupted
so where is the probleme ? is it from my client sending code or from my server receiving ?

EDIT: ive edited my client and server code to count the sending/receiving bytes and times

Client:
sends 20771 bytes in 21 times

Server:
receives 2083 bytes in 17 times

EDIT2: when doing "strlen(szBuffer)" from the client, all i get is not 1000 but sometimes 4 sometimes 96, 103...
is it a reading probleme ?

This post has been edited by James_Alex: 16 September 2011 - 02:58 AM

Was This Post Helpful? 0
  • +
  • -

#4 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Transferring file problem

Posted 16 September 2011 - 04:34 AM

The string functions will not work as explained above.

Binary files often contain the byte 0. The string functions take this to mean the end of the string, so it will not read any more! This is why you are getting small sections of the file only.

This means you have to use memcpy and similar functions, and keep track of the buffer size manually.
Was This Post Helpful? 2
  • +
  • -

#5 James_Alex  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 156
  • Joined: 21-August 09

Re: Transferring file problem

Posted 16 September 2011 - 06:16 AM

View PostPlasticineGuy, on 16 September 2011 - 12:34 PM, said:

The string functions will not work as explained above.

Binary files often contain the byte 0. The string functions take this to mean the end of the string, so it will not read any more! This is why you are getting small sections of the file only.

This means you have to use memcpy and similar functions, and keep track of the buffer size manually.


thanks, now i solved the sending size probleme
void CClient::Upload(char *szFile)
{
	// Prepare our packet
	stPacket packet;
	packet.iClientID = m_iClientID;
	// Open the file
	char szPath[128];
	sprintf(szPath, "%s/%s", m_szPath, szFile);
	FILE *pFile = fopen(szPath, "rb");
	if(!pFile)
		return;
	// Set the file pos to the end
	fseek(pFile, 0, SEEK_END);
	// Read 1000 bytes from the file
	void *pData = malloc(sizeof(char)*1001);
	int iReaded = fread(pData, 1, 1000, pFile);
	memcpy(packet.szBuffer, pData, sizeof(pData));
	packet.szBuffer[iReaded] = '\0'; 
	// Loop until the file reading is finished
	while(iReaded > 0)
	{
		// Setup the packet type
		packet.packetType = PACKET_TYPE_DOWNLOADING;
		// Send the packet
		GetSocket()->Send((const char *)&packet, sizeof(packet), NULL, -1);
		// Read the next buffer
		int iReaded = fread(pData, 1, 1000, pFile);
		memcpy(packet.szBuffer, pData, sizeof(pData));
		if(iReaded <= 0)
			break;
		packet.szBuffer[iReaded] = '\0';
		Sleep(10);
	}
	free(pData);
	fclose(pFile);
	// Prepare the finish packet
	packet.packetType = PACKET_TYPE_DOWNLOAD_FINISH;
	// Send the packet
	GetSocket()->Send((const char *)&packet, sizeof(packet), NULL, -1);
}



Server:

void CServer::StartDownload(char *szFile)
{
	m_pFile = fopen(szFile, "wb");
	if(!m_pFile)
		return;

	m_bDownloading = true;
}

void CServer::Download(char *szBuffer)
{
	if(!m_bDownloading)
		return;

	fwrite(szBuffer, 1, 1000, m_pFile);
}

void CServer::EndDownload()
{
	fclose(m_pFile);
	m_bDownloading = false;
}



now the 21 kb picture is sended, and i got another 21 kb pic received
but, the data sended are corrupted
even if i send a 1 kb text file, all i got is
fileΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜ


whole it should be
file successfully sended


Was This Post Helpful? 0
  • +
  • -

#6 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1327
  • View blog
  • Posts: 4,554
  • Joined: 19-February 09

Re: Transferring file problem

Posted 16 September 2011 - 07:36 PM

Hi, you goto the end of the file, why do you do that?

12	    // Set the file pos to the end
13	    fseek(pFile, 0, SEEK_END);


Was This Post Helpful? 0
  • +
  • -

#7 James_Alex  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 156
  • Joined: 21-August 09

Re: Transferring file problem

Posted 17 September 2011 - 12:51 AM

View Post#define, on 17 September 2011 - 03:36 AM, said:

Hi, you goto the end of the file, why do you do that?

12	    // Set the file pos to the end
13	    fseek(pFile, 0, SEEK_END);


its supposed to be like that
	// Set the file pos to the end
	fseek(pFile, 0, SEEK_END);
	// Get the file size
	int iSize = ftell(pFile);
	// Set the file back to the beginning
	fseek(pFile, 0, SEEK_SET);


so i get the file size and compare it with the sended bytes

probleme solved, all i had to do is to read the file directly into the szBuffer(no pData) then send the readed bytes in the packet, then write to the file depends on how many bytes i readed(not write always 1000)

thx for everyone who replied above and helped me solving it :)
[/code]

This post has been edited by James_Alex: 17 September 2011 - 01:42 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1