Callback

FTP Server

    A. Second Edition

    This is only a small lab assignment for comp445 which requires file to be able to transfer between client and

    server. What I actually have done is just to regroup all codes from sample to be class. The idea comes from Delphi

    which capsulate socket into a class. In this version, I just add some better message display and also allow

    multi files requests to be given by users.

    B.The problem

In network, a client program may request files to be put to or get from server program. You have to use the

socket to implement with a basic file transfer protocol by your own.

C.The idea of program
¡¡
First what I have in mind is that the client and server are almost same which implies that I can regroup those
¡¡
similar code of client and server into one class. I think this is done by Delphi.
¡¡
secondly, I may in near future intend to implement more complicated functionality. So, I try to write code in
¡¡
a rather OOP model.
¡¡

    D.The major functions

    ¡¡

    E.Further improvement

    It is said that TCP/IP won't lose packet of transfer, but I just continually plan to re-implement this functionality

    ¡¡

    F.File listing

    project client:

    1. error.h

    2. error.cpp

    3. log.h

    4. log.cpp

    5. packet.h

    6. socket.h

    7. socket.cpp

    8. client.cpp

    ¡¡

    project server:

    1. error.h

    2. error.cpp

    3. log.h

    4. log.cpp

    5. packet.h

    6. socket.h

    7. socket.cpp

    8. server.cpp

    workspace setup:

    1. create an empty "workspace".

    2. copy all above source code under the workspace.

    3. "new" a project named "client" by "add to current workspace".

    4. "new" a project named "server" by "add to current workspace".

    5. switch between two project and from "project" menu "add files" to project.

    6. in "project" menu choose "setting" and "link", add "wsock32.lib" at end.

    By doing above, you don't have to modify the "file path" of all head files.

    ¡¡

    file name: error.h

    #ifndef ERROR_H
    #define ERROR_H
    #include <stdio.h>
    #include <stdlib.h>
    #include "log.h"

    #define CANNOT_OPEN_LOG				0
    #define CANNOT_START_WSASTARTUP			1
    #define GETHOSTNAMEFAILED				2
    #define REMOTE_GETHOSTNAME_FAILED			3
    #define SOCKET_FAILED				4
    #define CONNECT_FAILED				5
    #define CANNOT_BIND_SOCKET				6
    #define CANNOT_SETUP_LISTEN				7
    #define CANNOT_OPEN_FILE_FOR_PUT			8
    #define CANNOT_OPEN_FILE_FOR_GET			9
    #define WAIT_TIME_OUT				10
    #define ERROR_DATA_RCVED				11

    void errorHandler(int errorNo);

    #endif

    file name: error.cpp

    #include "error.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>

    const int ErrorNumber=12;

    char* errorStrings[ErrorNumber]=
    {
    	"CANNOT_OPEN_LOG",
    	"Error in starting WSAStartup",
    	"GET HOST NAME FAILED",
    	"REMOTE_GETHOSTNAME_FAILED",
    	"SOCKET_FAILED",
    	"CONNECT_FAILED",
    	"CANNOT_BIND_SOCKET",
    	"CANNOT_SETUP_LISTEN",
    	"CANNOT_OPEN_FILE_FOR_PUT",
    	"CANNOT_OPEN_FILE_FOR_GET",
    	"WAIT_TIME_OUT",
    	"ERROR_DATA_RCVED",
    };

    void errorHandler(int errorNo)
    {
    	//printf("%s\n", errorStrings[errorNo]);
    	char errbuf[20];
    	writeLog(errorStrings[errorNo]);
    	sprintf(errbuf, "%d", GetLastError());
    	writeLog(errbuf);
    	exit(1);
    }

    ¡¡

    file name: log.h

    #ifndef LOG_H
    #define LOG_H
    #include <stdio.h>
    #include <stdlib.h>
    #include "error.h"

    typedef unsigned long ulong;

    //this will only be called once
    void startLog();

    //write anything you want
    ulong writeLog(char* buffer, bool toDisplay=false);

    #endif

    file name: log.cpp

    #include "log.h"
    #include <time.h>
    #include <windows.h>

    const int MaxLogNameLength=20;

    char logName[MaxLogNameLength];

    HANDLE log=NULL;

    void getTimeStamp(char* buf);

    void getTimeStamp(char* buf)
    {
    	char timeBuf[128];
    	_strtime(timeBuf);
    	strcpy(buf, timeBuf);
    	strcat(buf, " ");
    	_strdate(timeBuf);
    	strcat(buf, timeBuf);
    }

    void startLog()
    {
    	//getTimeStamp(logName);
    	//strcat(logName, timeBuf);

    	//sprintf(logName, "%u", time(0));
    	if (log==NULL)
    	{
    		strcpy(logName, "log");
    		strcat(logName, ".txt");
    		if ((log=CreateFile(logName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
    			FILE_ATTRIBUTE_NORMAL, NULL))==INVALID_HANDLE_VALUE)
    		{
    			errorHandler(CANNOT_OPEN_LOG);
    		}
    	}
    }

    ulong writeLog(char* buffer, bool toDisplay)
    {
    	char timeBuf[128];
    	//long distance;
    	ulong result, temp;
    	getTimeStamp(timeBuf);

    	strcat(timeBuf, ":\t");
    	//GetFileSize(log, &distance);
    	SetFilePointer(log, 0, NULL, FILE_END);
    	WriteFile(log, timeBuf, strlen(timeBuf), &result, NULL);
    	WriteFile(log, buffer, strlen(buffer), &result, NULL);
    	if (toDisplay)
    	{
    		printf("%s\n", buffer);
    	}
    	//strcpy(timeBuf, "\n");
    	timeBuf[0]=13;
    	timeBuf[1]=10;
    	timeBuf[2]=0;
    	WriteFile(log, timeBuf, strlen(timeBuf), &temp, NULL);
    	return result;
    }

    ¡¡

    ¡¡

    file name: packet.h

    #ifndef PACKET_H
    #define PACKET_H
    typedef unsigned short ushort;

    const int PacketDataSize=120;

    /*
    //if it is command, the "data" is the command string
    #define COMMAND       0x01
    //if it is information, "data" contains "filename",
    //"tail" contains the file size.
    #define INFORMATION   0x02
    //if it is data, "data" contains data, and "tail" contains "index"
    #define DATATYPE	  0x03
    //since we have the file size at "negotiation, we don't need sign of eof
    //but we have error which contains error msg in "data"
    #define ERRORTYPE	  0x04
    */

    //all size indicates the length of "data" field of struct packet
    //get contains the file name as "data", size of file as "tail"
    #define GETTYPE           '1'

    //put contains the file name as data, size of file as tail
    #define PUTTYPE           '2'

    //get reply just acknowledge the get information, the file name is in data, plus file size in tail
    #define GETREPLYTYPE	  '3'

    //just reply to put, and file name is still in the data.
    #define PUTREPLYTYPE	  '4'

    //whenever anything goes wrong
    #define ERRORTYPE	      '5'

    //the size of data is contained in size, in tail, it may contains the index number of packet
    #define DATATYPE	      '6'

    //this is a special packet, the data may also contains "data"
    #define EOFTYPE	          '7'

    struct Packet
    {
    	ushort type;
    	ushort size;
    	unsigned long tail;
    	char data[PacketDataSize];
    };

    #endif

    ¡¡

    file name: socket.h

    #ifndef SOCKET_H
    #define SOCKET_H
    #include <winsock.h>
    #include "packet.h"

    #define REQUEST_PORT 0x7070

    //int port=REQUEST_PORT;

    const int MessageBufferSize=128;

    class Socket
    {

    private:
    	union
    	{
    		struct sockaddr generic;
    		struct sockaddr_in ca_in;
    	}ca;
    	//socket data types
    	fd_set readfds;
    	bool bServer;
    	int port;
    	SOCKET s, ser;
    	SOCKADDR_IN sa;         // filled by bind
    	SOCKADDR_IN sa_in;      // fill with server info, IP, port
    	HOSTENT *hp;
    	HOSTENT *rp;
    	WSADATA wsadata;
    	char buffer[128];
    	HANDLE hfile;
    	void writeToLog(bool toDisplay=false);
    	void initialize();
    	void serverConn();
    	void recvFile(unsigned long fileSize);
    	void sendFile(unsigned long fileSize);
    	void connectTo(char* serverName);
    public:
    	char localhost[11];
        char remotehost[11];
    	void clientConn(char* serverName);
    	Packet incoming, outgoing;
    	char msg[256];
    	~Socket();
    	Socket(bool isServer=false);
    	void listening();
    	int sendPacket(const Packet& packet);
    	int recvPacket(Packet& packet);
    	int sendMsg();
    	int recvMsg();
    	void tranFile(Packet& packet);
    };

    #endif

    ¡¡

    file name: socket.cpp

    #include <winsock2.h>
    #include <time.h>
    #include "socket.h"
    #include <string.h>
    #include "log.h"
    #include "error.h"
    #include "packet.h"

    const long TimeOutLimit=10;

    //add a little indicator of ">" to indicating the progress of file transfer
    void Socket::sendFile(unsigned long fileSize)
    {
    	int counter=0, times2print=fileSize/PacketDataSize;
    	char msgbuf[128];
    	bool begin=false;
    	if (times2print>80)
    	{
    		times2print=times2print/80;
    	}
    	else
    	{
    		//otherwise, print everytime
    		times2print=1;
    	}
    	while (ReadFile(hfile, outgoing.data, PacketDataSize, (LPDWORD)&outgoing.size, NULL)
    		&&outgoing.size!=0)
    	{
    		outgoing.type=DATATYPE;
    		sendPacket(outgoing);
    		if (!begin)
    		{
    			begin=true;
    			sprintf(msgbuf, "Begin sending first byte from %s\n", remotehost);
    			writeLog(msgbuf, true);
    		}
    		counter++;
    		if (counter==times2print)
    		{
    			counter=0;
    			printf(">");
    		}
    	}
    	outgoing.type=EOFTYPE;
    	sendPacket(outgoing);
    	sprintf(msgbuf, "End of transmission to %s\n", remotehost);
    	writeLog(msgbuf, true);
    	printf("Succeed sending total %d bytes\n", fileSize);
    	CloseHandle(hfile);
    	shutdown(s, SD_BOTH);
    	//if (bServer)
    	{
    		closesocket(s);
    	}
    }

    void Socket::recvFile(unsigned long fileSize)
    {
    	double number;
    	int counter=0, times2print=fileSize/PacketDataSize;
    	bool begin=false;
    	char msgbuf[128];
    	//divide into 80 times for printing progress
    	if (times2print>80)
    	{
    		times2print=times2print/80;
    	}
    	else
    	{
    		//otherwise, print everytime
    		times2print=1;
    	}
    	while (true)
    	{
    		if (recvPacket(incoming)>0)
    		{
    			if (incoming.type==DATATYPE)
    			{
    				if (!begin)
    				{
    					begin=true;
    					sprintf(msgbuf, "Begin recieving first byte from %s\n", remotehost);
    					writeLog(msgbuf, true);
    				}
    				WriteFile(hfile, incoming.data, (DWORD)(incoming.size), (LPDWORD)&number, NULL);
    				counter++;
    				if (counter==times2print)
    				{
    					counter=0;
    					printf(">");
    				}
    			}
    			else
    			{
    				if (incoming.type==EOFTYPE)
    				{
    					sprintf(msgbuf, "End of transmission from %s\n", remotehost);
    					writeLog(msgbuf, true);
    					break;
    				}
    				else
    				{
    					errorHandler(ERROR_DATA_RCVED);
    				}
    			}
    		}
    	}
    	if (SetEndOfFile(hfile)>0)
    	{
    		printf("Succeed receiving total %d bytes\n", fileSize);
    	}
    	CloseHandle(hfile);
    	int i = shutdown(s, SD_BOTH);
    	//if (bServer)
    	{
    		i = closesocket(s);
    		int x = send (s, "fjdskl", 6, 0);
    	}
    }

    void Socket::tranFile(Packet& packet)
    {
    	char msgbuf[128];

    	if (!bServer)
    	{
    		//for client, these are to be sent
    		switch(packet.type)
    		{
    		case PUTTYPE:
    			sprintf(msgbuf, "prepare to send file %s", packet.data);
    			writeLog(msgbuf);
    			if ((hfile=CreateFile(packet.data, GENERIC_READ, 0, NULL, OPEN_EXISTING,
    				0, 0))==NULL)
    			{
    				//if cannot open file, then nothing is sent.
    				errorHandler(CANNOT_OPEN_FILE_FOR_PUT);
    				//packet.type=ERRORTYPE;
    				//packet.tail=CANNOT_OPEN_FILE_FOR_PUT;
    			}
    			else
    			{
    				packet.tail=GetFileSize(hfile, NULL);
    				sendPacket(packet);
    				//for client have to wait for reply
    				long start=time(0);
    				do
    				{
    					if (time(0)-start>TimeOutLimit)
    					{
    						errorHandler(WAIT_TIME_OUT);
    					}
    					recvPacket(incoming);
    				}while (incoming.type!=PUTREPLYTYPE);
    				sendFile(packet.tail);
    			}
    			break;
    		case GETTYPE:
    			sprintf(msgbuf, "prepare to receive file %s", packet.data);
    			writeLog(msgbuf);
    			if ((hfile=CreateFile(packet.data, GENERIC_WRITE, 0, NULL,
    				CREATE_ALWAYS, 0, 0))==NULL)
    			{
    				//if cannot open file, then nothing is sent
    				errorHandler(CANNOT_OPEN_FILE_FOR_GET);
    			}
    			else
    			{
    				//send out the request
    				sendPacket(packet);
    				long start=time(0);
    				do
    				{
    					if (time(0)-start>TimeOutLimit)
    					{
    						errorHandler(WAIT_TIME_OUT);
    					}
    					recvPacket(incoming);
    				}while (incoming.type!=GETREPLYTYPE);
    				recvFile(incoming.tail);
    			}
    			break;
    		}
    	}
    	else
    	{
    		//for server, this is to be replied
    		switch (packet.type)
    		{
    			case PUTTYPE:
    			//strncpy(fileName, packet.data, packet.size);
    			sprintf(msgbuf, "Host %s requested file %s to be received.\n",
    				remotehost, packet.data);
    			writeLog(msgbuf, true);
    			printf("Prepare receiving file from %s, waiting...\n", remotehost);

    			if ((hfile=CreateFile(packet.data, GENERIC_WRITE, 0, NULL,
    				CREATE_ALWAYS, 0, 0))==NULL)
    			{
    				//if cannot open file, then nothing is sent.
    				errorHandler(CANNOT_OPEN_FILE_FOR_PUT);
    				//packet.type=ERRORTYPE;
    				//packet.tail=CANNOT_OPEN_FILE_FOR_PUT;
    			}
    			else
    			{
    				//GetFileSize(hfile, &packet.tail);
    				//this is to reply put request
    				outgoing.type=PUTREPLYTYPE;
    				outgoing.size=packet.size;
    				strncpy(outgoing.data, packet.data, packet.size);
    				outgoing.tail=packet.tail;
    				sendPacket(outgoing);
    				//pass size of file as param
    				recvFile(outgoing.tail);
    			}
    			break;
    		case GETTYPE:
    			sprintf(msgbuf, "Host %s requested file %s to be send.\n", remotehost, packet.data);
    			writeLog(msgbuf, true);
    			printf("Prepare sending file to %s, waiting...\n", remotehost);
    			//strncpy(fileName, packet.data, packet.size);
    			if ((hfile=CreateFile(packet.data, GENERIC_READ, 0, NULL, OPEN_EXISTING,
    				0, 0))==NULL)
    			{
    				//if cannot open file, then nothing is sent
    				errorHandler(CANNOT_OPEN_FILE_FOR_GET);
    			}
    			else
    			{
    				//send out the request
    				outgoing.type=GETREPLYTYPE;
    				outgoing.size=packet.size;
    				strncpy(outgoing.data, packet.data, packet.size);
    				outgoing.tail=GetFileSize(hfile, NULL); //file size is param
    				//
    				sendPacket(outgoing);
    				sendFile(outgoing.tail);
    			}
    			break;
    		}
    	}
    }

    void Socket::writeToLog(bool toDisplay)
    {
    	writeLog(buffer, toDisplay);

    	/*
    	<< "wsadata.wVersion "       << wsadata.wVersion       << endl
    	<< "wsadata.wHighVersion "   << wsadata.wHighVersion   << endl
    	<< "wsadata.szDescription "  << wsadata.szDescription  << endl
    	<< "wsadata.szSystemStatus " << wsadata.szSystemStatus << endl
    	<< "wsadata.iMaxSockets "    << wsadata.iMaxSockets    << endl
    	<< "wsadata.iMaxUdpDg "      << wsadata.iMaxUdpDg      << endl;
    	*/
    }

    int Socket::sendPacket(const Packet& packet)
    {
    	int result=0;
    	result=send(s, (char*)(&packet), sizeof(Packet), 0);
    	return result;
    }

    int Socket::recvPacket(Packet& packet)
    {
    	int result=0;
    	result=recv(s, (char*)(&packet), sizeof(Packet), 0);
    	return result;
    }

    int Socket::sendMsg()
    {
    	int result=0;
    	result=send(s, msg, strlen(msg), 0);
    	return result;
    }

    int Socket::recvMsg()
    {
    	int result=0;
    	msg[0]='\0';
    	result=recv(s, msg, MessageBufferSize, 0);
    	msg[result]='\0';
    	return result;
    }

    void Socket::connectTo(char* serverName)
    {
    	strcpy(remotehost, serverName);
    	sprintf(buffer, "Remote host name is: \"%s\"", remotehost);
    	writeToLog();
    	if((rp=gethostbyname(remotehost)) == NULL)
    	{
    		  //throw "remote gethostbyname failed\n";
    		errorHandler(REMOTE_GETHOSTNAME_FAILED);
    	}

          /* For UDP protocol replace SOCK_STREAM with SOCK_DGRAM */

    	  //Specify server address for client to connect to server.
    	memset(&sa_in,0,sizeof(sa_in));
    	memcpy(&sa_in.sin_addr,rp->h_addr,rp->h_length);
    	sa_in.sin_family = rp->h_addrtype;
    	sa_in.sin_port = htons(port);

    	//Display the host machine internet address
    	sprintf(buffer, "Connecting to remote host:%s\n", inet_ntoa(sa_in.sin_addr));
    	writeLog(buffer);

    	//Connect Client to the server
    	if (connect(s,(LPSOCKADDR)&sa_in,sizeof(sa_in)) == SOCKET_ERROR)
    	//throw "connect failed\n";
    	{
    		errorHandler(CONNECT_FAILED);
    	}
    }

    void Socket::clientConn(char* serverName)
    {
    	if((s = socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
    		  //throw "Socket failed\n";
    	{
    		errorHandler(SOCKET_FAILED);
    	}
    	connectTo(serverName);
    }

    void Socket::serverConn()
    {
    	if((ser = socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
    		  //throw "Socket failed\n";
    	{
    		errorHandler(SOCKET_FAILED);
    	}
    	//Fill-in Server Port and Address info.
        sa.sin_family = AF_INET;
    	sa.sin_port = htons(port);
    	sa.sin_addr.s_addr = htonl(INADDR_ANY);

    	//Bind the server port

    	if (bind(ser,(LPSOCKADDR)&sa,sizeof(sa)) == SOCKET_ERROR)
    	{
    		errorHandler(CANNOT_BIND_SOCKET);
    		//throw "can't bind the socket";
    	}

        sprintf(buffer, "bind is successful\n");
    	writeToLog();

    	//Successfull bind, now listen for client requests.

    	sprintf(buffer, "Ftp server starting at host:[%s]\n", localhost);
    	writeLog(buffer, true);
    	sprintf(buffer, "Waiting to be contacted for transferring files...");
    	writeLog(buffer, true);

    	//listening();
    }

    void Socket::listening()
    {
    	int infds=1, outfds=0;//, outNum, inNum;
    	int calen=sizeof(ca);
    	struct timeval timeout;
    	hostent* phost;

    	if(listen(ser,10) == SOCKET_ERROR)
    	{
    		errorHandler(CANNOT_SETUP_LISTEN);
    	}
         //    throw "couldn't  set up listen on socket";
        else
    	{
    		sprintf(buffer, "Listen was successful\n");
    		writeToLog();
    	}

    	const struct timeval *tp=&timeout;
    	FD_ZERO(&readfds);

    	//wait loop

    	while(true)
    	{
    		FD_SET(ser,&readfds);  //always check the listener

    		if(!(outfds=select(infds,&readfds,NULL,NULL,tp))) {}

    		else if (outfds == SOCKET_ERROR) throw "failure in Select";

    		else if (FD_ISSET(ser,&readfds))
    		{
    			//cout << "got a connection request" << endl;
    			sprintf(buffer, "got a connection request\n");
    			writeToLog();
    		}

     		//Found a connection request, try to accept.
    		if((s=accept(ser,&ca.generic,&calen))==INVALID_SOCKET)
    		{
    			throw "Couldn't accept connection\n";
    		}
    		else
    		{
    			sprintf(buffer, "accepted connection from %s %d\n",
    				inet_ntoa(ca.ca_in.sin_addr), htons(ca.ca_in.sin_port));
    			//calen=sizeof(ca);
    			//getpeername(s, &ca.generic, &calen);
    			//printf("generic.data %s,\n", ca.generic.sa_data);
    			phost=gethostbyaddr((char*)&ca.ca_in.sin_addr, sizeof(ca.ca_in.sin_addr), AF_INET);
    			//printf("%s\n", phost->h_name);
    			strcpy(remotehost, phost->h_name);
    			writeToLog();
    			break;
    		}

    	/*
    		if ((inNum=recvMsg())>0)
    		{
    			printf("message from client %s\n", msg);
    		}
    		if ((outNum=sendMsg())>0)
    		{
    			printf("message to client %s\n", msg);
    		}
    		*/
    	}
    }

    Socket::~Socket()
    {
    	closesocket(s);
    	if (bServer)
    	{
    		closesocket(ser);
    	}
    	WSACleanup();
    }

    Socket::Socket(bool isServer)
    {
    	initialize();
    	bServer=isServer;
    	if (!isServer)//CLIENT
    	{
    		//clientConn();
    	}
    	else
    	{
    		serverConn();
    	}
    }

    void Socket::initialize()
    {
    	startLog();
    	port=REQUEST_PORT;
    	if (WSAStartup(0x0202,&wsadata)!=0)
    	{
    		errorHandler(CANNOT_START_WSASTARTUP);
    	}
    	else
    	{
    		strcpy(buffer, "WSAStartup was successful\n");
    		writeToLog(false);
    		sprintf(buffer, "%s %d\n", "wsadata.wVersion ", wsadata.wVersion);
    		writeToLog(false);
    		sprintf(buffer, "%s %d\n", "wsadata.wVersion ", wsadata.wHighVersion);
    		writeToLog(false);
    		sprintf(buffer, "%s %s\n", "wsadata.szDescription ", wsadata.szDescription);
    		writeToLog(false);
    		sprintf(buffer, "%s %s\n", "wsadata.szSystemStatus ", wsadata.szSystemStatus);
    		writeToLog(false);
    		sprintf(buffer, "%s %d\n", "wsadata.iMaxSockets ", wsadata.iMaxSockets);
    		writeToLog(false);
    		sprintf(buffer, "%s %d\n", "wsadata.iMaxUdpDg ", wsadata.iMaxUdpDg);
    		writeToLog(false);
    	 //WriteFile(test,buffer,sizeof(buffer),&dwtest,NULL);
    	}
        //Display name of local host.

    	gethostname(localhost,10);
    	/*
    	sprintf(buffer, "%s%s%s\n", "server starting on host [", localhost, "]");
    	writeToLog(true);
    	sprintf(buffer, "Waiting to be contacted for transferring files...");
    	writeToLog(true);
    	*/

    	if((hp=gethostbyname(localhost)) == NULL)
    		//throw "gethostbyname failed\n";
    	{
    		errorHandler(GETHOSTNAMEFAILED);
    	}
    		  //Create the socket

    }

    ¡¡

    file name: client.cpp

    /* send and receive codes between client and server */
    /* This is your basic WINSOCK shell */
    #include <stdio.h>
    #include <stdlib.h>
    #include "socket.h"
    #include "packet.h"
    #include "log.h"

    //reference for used structures

    /*  * Host structure

    struct  hostent {
            char    FAR * h_name;             official name of host *
            char    FAR * FAR * h_aliases;    alias list *
            short   h_addrtype;               host address type *
            short   h_length;                 length of address *
            char    FAR * FAR * h_addr_list;  list of addresses *
    #define h_addr  h_addr_list[0]            address, for backward compat *
    };

        * Socket address structure

    struct sockaddr_in {
            short   sin_family;
            u_short sin_port;
            struct  in_addr sin_addr;
            char    sin_zero[8];
    }; */

    int main()
    {
    	char msgbuf[20];
    	char serverName[10];
    	Socket client;
    	//char type;

    	//char type;//, ch;
    	//HANDLE hfile;
    	//char fileName[128];
    	//FILE* stream;
    	//int counter;

    	//Packet packet;
    	//printf("type exit for quit\n");
    	while (true)
    	{

    		printf("\n%s", "Type name of ftp server(quit for exit):");

    		//Ask for name of remote server
    		scanf("%s", serverName);
    		if (strcmp(serverName, "quit")==0)
    		{
    			break;
    		}
    		client.clientConn(serverName);
    		printf("\nType name of file to be transferred:");
    		//strcpy(client.outgoing.data, "nicktest.txt");
    		scanf("%s", client.outgoing.data);

    		//packet.type=packet.type-'0';//change to
    		client.outgoing.size=strlen(client.outgoing.data);
    		printf("Type direction of transfer:( get ;  put)");
    		//client.outgoing.type='2';
    		scanf("%s", msgbuf);
    		if (strcmp(msgbuf, "get")==0)
    		{
    			client.outgoing.type=GETTYPE;
    		}
    		else
    		{
    			client.outgoing.type=PUTTYPE;
    		}
    		printf("Sent request to %s, waiting...\n", serverName);

    		client.tranFile(client.outgoing);
    		//client.initialize();
    	}

    /*
    	while (true)
    	{
    		//scanf("%s\n", client.msg);
    		printf("type your message:");
    		//gets(msgbuf);

    		//scanf("type:%c\ndata:%s\n", &type, msgbuf);
    		//sprintf(&client.msg[1], "%u", strlen(msgbuf));
    		//sprintf(&client.msg[sizeof(int)+1], "%s", msgbuf);
    		client.msg[0]=COMMAND;
    		//gets(msgbuf);
    		strcpy(msgbuf, "their is message here");

    		sprintf(&client.msg[1], "%u", strlen(msgbuf));
    		sprintf(&client.msg[sizeof(int)+1], "%s", msgbuf);

    		//packet.size=strlen(msgbuf);
    		//packet.tail=0xff;
    		sprintf(&client.msg[PacketDataSize+sizeof(int)+1], "%d", 158);

    		client.sendPacket();
    	}
    	*/

        return 0;
    }

    /*

    */

    file name: server.cpp

    #include "socket.h"
    #include "packet.h"
    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {
    	Socket server(true);
    	//int size, tail;
    	//char type;
    	//char mbuf[128];
    	//printf("I am waiting...\n");
    	while (true)
    	{
    		server.listening();
    		if (server.recvPacket(server.incoming)>0)
    		{
    			printf("User \"%s\" requested file \"%s\" to be sent\n", server.remotehost,
    				server.incoming.data);
    			server.tranFile(server.incoming);

    			printf("Ftp server starting at host:[%s]\n", server.localhost);

    			printf("Waiting to be contacted for transferring files...");

    		}

    	}

    	/*
    	while (true)
    	{
    		if (server.recvMsg()>0)
    		{
    			//printf("message from client:%s\n", server.msg);
    			sscanf(server.msg, "%1c", &type);
    			sscanf(&server.msg[1], "%u", &size);
    			printf("type:%c\nsize:%u\n", type, size);
    			strncpy(mbuf, &server.msg[sizeof(int)+1], size);
    			mbuf[size]='\0';
    			sscanf(&server.msg[sizeof(int)+1+PacketDataSize], "%u", &tail);
    			printf("data:%s\ntail:%u\n", mbuf, tail);
    		}
    	}
    	*/

    	return 0;
    }

    How to run?

    1. run server first.

    2. run client and type in computer name of server.

    3. type in command "get" or "put" and file name which must be in current file path.

    ¡¡