Advertisement

Simple FTP question...

Started by October 03, 2002 11:14 AM
1 comment, last by TheTempest 22 years, 4 months ago
Hello, I have a small question. I have written a multithreaded server and it recv''s a login packet correctly and a msg packet correctly. Client side everything works, including a file packet. B4 everything is sent on the client, it''s all there the file is correctly stored in the pointer. But after we sent the file across the network, the server recv''s the file packet but the pointer that is supose to contain the data in the file, when i cout it, i get nothing not even a memory address when i take the address of it... following is the source code.
  
#include <fstream.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <winsock2.h>

#define GENERAL_PACKET 0
#define LOGIN_PACKET   1
#define CHAT_PACKET    2
#define FILE_PACKET    3

//#define DEBUG          1


class GeneralPacket
{
	public:
		int isize;
		int itype;
};

class LoginPacket : public GeneralPacket
{
	public:
		char szName[64];
		char szPass[64];
};

class TextMsg : public GeneralPacket
{
	public:
		char message[512];
		char szName[64];
};

class FilePacket : public GeneralPacket
{
	public:
		char *fileData;
		char fileName[64];
};

void sendPacket(int pSize, char* packet, SOCKET outSocket)
{
	if(send(outSocket, packet, pSize, 0))
	{
		cout << "Send Passed\n";
		flush(cout);
	}
	else
	{
		cout << "Send Failed\n";
		flush(cout);
	}
}

void setupSockets();
void clientThread(void *param);
void listenThread(void *param);

int g_iQuit = 0;
HANDLE g_hListenThread;
DWORD dwListenThreadID;
HANDLE g_hClientThread;
DWORD dwClientThreadID;

class serverSocket
{
	public:
		void Bind(int iPort);
		void startup();
	private:
		SOCKET mySocket;
};

void main()
{
	WORD version = MAKEWORD(2,2);
	WSADATA wsaData;
	serverSocket srvSocket;
	g_iQuit = 0;

	if(WSAStartup(version, &wsaData) != 0)
	{
		cout << "WSAStartup() failed\n";
		flush(cout);
	}
	
	cout << "Starting Server...\n";
	flush(cout);
	srvSocket.startup();

	while(true)
	{
		// Wait for user to hit quit

	}

	WaitForSingleObject(g_hListenThread, INFINITE);
	CloseHandle(g_hListenThread);
	cout << "Listening Thread Closed\n";
	flush(cout);
}

void serverSocket::startup()
{
	Bind(4000);

	cout << "Starting listen thread\n";
	flush(cout);
	g_hListenThread = CreateThread(NULL, 
					NULL, 
					(LPTHREAD_START_ROUTINE)&listenThread,
					(VOID*)mySocket,
					NULL,
					&dwListenThreadID);
}

void serverSocket::Bind(int iPort)
{
	sockaddr_in saServerAddress;
		
	mySocket = socket(AF_INET, SOCK_STREAM, 0);

	if(mySocket == INVALID_SOCKET)
	{
		cout << "Error at socket(): " << WSAGetLastError() << "\n";
		flush(cout);
		return;
	}

	memset(&saServerAddress, 0, sizeof(sockaddr_in));

	saServerAddress.sin_family = AF_INET;
	saServerAddress.sin_addr.s_addr = htons(INADDR_ANY);
	saServerAddress.sin_port = htons(iPort);

	if(bind(mySocket, (sockaddr*) &saServerAddress, sizeof(sockaddr)) == SOCKET_ERROR)
	{
		#ifdef DEBUG
			cout << "Error at bind(): " << WSAGetLastError() << "\n";
			flush(cout);
		#endif
	}
	else
		return;
}

void listenThread(void *param)
{
	SOCKET listeningSocket = (SOCKET)param;

	#ifdef DEBUG
		cout << "Entering listening thread\n";
		flush(cout);
	#endif

	int nRet;
	int size = sizeof(SOCKADDR_IN);
	SOCKADDR addr_Cli;
	SOCKET client;

	nRet = listen(listeningSocket, 10);

	if(nRet == INVALID_SOCKET)
	{
		#ifdef DEBUG
			cout << "Error at listen\n";
			cout << "Last Error: " << WSAGetLastError() << "\n";
			flush(cout);
		#endif

		ExitThread(0);
	}
	else
	{
		#ifdef DEBUG
			cout << "Listen passed\n";
			flush(cout);
		#endif
	}

	while(g_iQuit != 1)
	{
		client = accept(listeningSocket, (struct sockaddr*)&addr_Cli, &size);
		if(client == INVALID_SOCKET)
		{
			#ifdef DEBUG
				cout << "Error at accept in listening thread\n";
				flush(cout);
				ExitThread(0);
			#endif
		}
		else
		{
			cout << "Accepted client\n";
			g_hClientThread = CreateThread(NULL,
							NULL,
							(LPTHREAD_START_ROUTINE)&clientThread,
							(void*)client,
							NULL,
							&dwClientThreadID);
		}

		client = INVALID_SOCKET;
	}

	closesocket(listeningSocket);
	closesocket(client);

	#ifdef DEBUG
		cout << "Exiting Listening Thread\n";
		flush(cout);
	#endif
}

void clientThread(void *param)
{
	SOCKET client = (SOCKET)param;
	#ifdef DEBUG
		cout << "Entering Client Thread\n";
		flush(cout);
	#endif

	char *recvData = NULL;
	GeneralPacket *PGen = NULL;
	LoginPacket *Login = NULL;
	char uName[64];
	strcpy(uName, "NULL");

	recvData = new char[32768];
	int recvSize = -1;

	while(g_iQuit != 1)
	{
		recvSize = recv(client, recvData, 32768, 0);

		if(recvSize == 0)
		{
			if(uName != "NULL")
				cout << "Client, " << uName << ", has disconnected\n";
			flush(cout);
			shutdown(client, SD_SEND);
			closesocket(client);
			#ifdef DEBUG
				cout << "Exiting client thread\n";
				flush(cout);
			#endif
			ExitThread(0);
		}
		else if(recvSize == SOCKET_ERROR)
		{
			cout << "Receive failed\n";
			cout << "Last Error: " << WSAGetLastError() << "\n";
			flush(cout);
			ExitThread(0);
		}

		PGen = (GeneralPacket*)recvData;

		#ifdef DEBUG
			cout << "Amount of data received: " << recvSize << "\n";
		#endif

		if(PGen->itype == LOGIN_PACKET)
		{
			#ifdef DEBUG
				cout << "Received a Login Packet\n";
				cout << "at a size of: " << recvSize << "\n";
				flush(cout);
			#endif

			Login = (LoginPacket*)recvData;

			strcpy(uName, Login->szName);
			cout << "User logged in: " << Login->szName << "\n";
			flush(cout);
		}
		else if(PGen->itype == CHAT_PACKET)
		{
			TextMsg *MESSAGE;
			MESSAGE = (TextMsg*)recvData;
			#ifdef DEBUG
				cout << "Received a chat packet\n";
			#endif
			cout << MESSAGE->szName << ": " << MESSAGE->message << "\n" << flush;
		} 
		else if(PGen->itype == FILE_PACKET)
		{
			FilePacket *File = NULL;
			File = (FilePacket*)recvData;
			cout << "Receiving a file of size " << File->isize << "\n";
			ofstream prnt;
			prnt.open("ftest.txt");
			prnt << File->fileData;
			cout << "File Data: " << File->fileData << endl;
			prnt.close();
			cout.flush();
		}
		else
		{
			cout << "Unrecognized Packet\n";
			flush(cout);
		}
	}

	closesocket(client);

	#ifdef DEBUG
		cout << "Exiting Client Thread\n";
		flush(cout);
	#endif
}
/[source]

THANKS  
"There are no such things as stupid questions... Just stupid people " -Me
"There are no such things as stupid questions...Just stupid people :)"-Me
Send ''&packet'' not just ''packet''

You''re just sending over the memory address of packet. Also make sure you''re sending the right size. You may only be sending the 4 bytes that make up the pointer''s address.

Ben


IcarusIndie.com [ The Rabbit Hole | The Labyrinth | DevZone | Gang Wars | The Wall | Hosting | Dot Com | GameShot ]
Advertisement
as above.

some hints:
send 1460 bytes per packet, why?
packet is 1500 bytes -20 header TCP/IP -20 header IPX = 1460 bytes of data in one packet. Its much faster, and you dont mind losing 12packet of all 13 (if Nagle algorithm is enabled, winsock will make x packets instead of one)

This topic is closed to new replies.

Advertisement