| |
//======================================================================
// By Xuan Sun
// Dec. 22, 99
// File: client.cpp
// Description: This is a FTP client. It requests connection the
// server, and being handed over to a thread (without knowing it).
// It receives a data file from the thread, as if a customer gets
// a menu when entering a restuarant. This data file contains a
// list of files and folders that are available for people to
// download and upload to.
// An array of objects, itemRecord, are generated from this
// data file. They are use all through the file transfer process.
// Clients communicate with the server what they want to do
// by sending the index number of this array.
//=======================================================================
#include windows.h // not able to use brackets because of HTML tags
#include stdio.h
#include string.h
#include stdlib.h
#include time.h
#include "item_record.h"
void upload(SOCKET &);
void download(SOCKET &);
void create(void);
void retrieve(void);
void display(SOCKET &);
void load(int, SOCKET &);
char loadDir[50]; // used in upload and download functions
itemRecord currItem; // the item that is being processed
itemRecord items[11];
void main()
{
//====================================================
// START: Initialize Socket Info
//====================================================
char ipAddrServer[16];
struct sockaddr_in ClientAddr, ServerAddr;
int ServerSize=sizeof(sockaddr_in);
int err;
WORD wVersionRequested;
WSADATA wsaData;
SOCKET s;
//====================================================
// END: Initialize Socket Info
//====================================================
printf("Please enter the IP address of the server: ");
gets(ipAddrServer);
//====================================================
// START: Prepare Socket
//====================================================
wVersionRequested = MAKEWORD( 1,1);
if (WSAStartup(wVersionRequested, &wsaData)!=0) {
printf("In WSAStartup, CLIENT Error: %d\n",WSAGetLastError());
exit(1);
}
s=socket(AF_INET, SOCK_STREAM, 0);
if (s==INVALID_SOCKET){
printf("In socket, CLIENT Error: %d\n",WSAGetLastError());
exit(2);
}
ClientAddr.sin_family=AF_INET;
ClientAddr.sin_addr.s_addr=htonl(INADDR_ANY);
ClientAddr.sin_port=htons(0);
if(bind(s,(struct sockaddr *)&ClientAddr,sizeof(sockaddr_in))==SOCKET_ERROR) {
printf("In bind, CLIENT Error: %d\n",WSAGetLastError());
exit(3);
}
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_addr.s_addr=inet_addr(ipAddrServer);
ServerAddr.sin_port=htons(6000);
err=connect(s, (struct sockaddr *)&ServerAddr,sizeof(sockaddr_in));
if (err==SOCKET_ERROR) {
printf("In connect, CLIENT Error: %d\n",WSAGetLastError());
exit(4);
}
//====================================================
// END: Prepare Socket
//====================================================
printf(" The server is connected.\n");
//to download record file from the server
strcpy(loadDir,"record.txt");
download(s);
//initialize record list
create();
//read list from file
retrieve();
//display records
printf("\n\nThis program is ready to do file transfer now\n");
printf("There are some facts which are helpful to know:\n");
printf("1. File name size and file directory size should be less than 50.\n");
printf("2. Blanks in file names and directories are not allowed.\n");
printf("Advanturous acts beyond these rules may cause the program to abort.\n");
printf("Soon you'll see the list of files you can download, and folders you can upload to.\n");
printf("They are displayed one by one. Options to process will be provided after each one.\n");
printf("Please key in your choice as INSTRUCTED.\n");
display(s);
printf("Thank you for using this program.\nHave a brilliant day!\n");
Sleep(500);
closesocket(s);
WSACleanup();
}
//====================================================
// START: Download Function
// Please refer to the documentation of
// upload function in server.cpp
//====================================================
void download(SOCKET &downloadSocket)
{
HANDLE writetofile;
char moveBuffer[1100];
char sNumRead[3], *stopString; // for converting from char[] to ul
unsigned long numRead, numWritten;
int j=3, counter=0, err;
double i;
writetofile=CreateFile(
loadDir,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (writetofile==INVALID_HANDLE_VALUE) {
printf("in WRITEHANDLE error: %d.\n", GetLastError);
exit(2);
}
//=========================================
do{
// recv how long the next buffer is
err=recv(downloadSocket,sNumRead, j,0);
if (err==SOCKET_ERROR) {
printf("In recv numRead, THREAD Error: %d\n",WSAGetLastError());
getchar();
exit(6);
}
i=strtod(sNumRead, &stopString);
numRead = strtoul( sNumRead, &stopString, 10 );
if (numRead!=0) {
// recv buffer from the server
err=recv(downloadSocket, moveBuffer, numRead,0);
if (err==SOCKET_ERROR) {
printf("In recv numRead, THREAD Error: %d\n",WSAGetLastError());
getchar();
exit(7);
}
// write buffer to the local file
err=WriteFile(
writetofile,
moveBuffer,
numRead,
&numWritten,
NULL);
if (err==NULL){
printf("in WriteFile error: %d.", GetLastError);
exit(3);
}
counter=counter+(int)numWritten;
}
}while( numRead!=0);
printf("Total number of bytes received: %d\n", counter);
err=CloseHandle(writetofile);
if (err==NULL){
printf("in close writetohandle error: %d.", GetLastError);
exit(5);
}
}
//====================================================
// START: Upload Function
// Please refer to the documentation of
// download function in server.cpp
//====================================================
void upload(SOCKET &uploadSocket)
{
//===================================
HANDLE filehandle;
char moveBuffer[1100];
char sNumRead[3];
unsigned long numRead;
int j=3, err, counter=0;
filehandle=CreateFile(
loadDir,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (filehandle==INVALID_HANDLE_VALUE){
printf("in READHANDLE error: %d.\n", GetLastError);
exit(1);
}
//===================================
do {
//======================================
err=ReadFile(
filehandle,
moveBuffer,
100,
&numRead,
NULL);
if (err==NULL){
printf("in ReadFile error: %d.\n", GetLastError);
exit(3);
}
_ultoa(numRead, sNumRead, 10);
err=send(uploadSocket, sNumRead, j,0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
if (numRead!=0) {
err=send(uploadSocket, moveBuffer, numRead,0);
if (err==SOCKET_ERROR) {
printf("In send moveBuffer, Client error: %d\n",WSAGetLastError());
exit(11);
}
counter=counter+(int)numRead;
}
//======================================
}while(numRead!=0);
printf("Total amount of bytes transfered: %d\n", counter);
err=CloseHandle(filehandle);
if (err==NULL){
printf("in close filehandle error: %d.", GetLastError);
exit(4);
}
}
//===============================================================
// START: load Function
// This function tells the server side what to do, download
// or upload or quit, which file or folder to work on,
// according to what is choose in display.
//===============================================================
void load(int i, SOCKET &loadSocket)
{
int err, idLen;
char sIdLen[3];
char itemId[10], itemName[50], itemDir[50], itemComm[100];
char uploadFileName[50];
// get what the current item is, especially the index number
currItem.getRecord(itemId, itemName, itemDir, itemComm);
idLen=strlen(itemId);
_itoa(idLen, sIdLen, 10 );
// if the user chooses to download, and the record is a file, then do download
if (i==1 && strcmp(itemComm, "file")==0) {
//====================================
// This part is repeated in else, instead of being
// put before the if statement. It's because this
// structure guarantees that the itemId is sent only
// when the user is making right choices.
err=send(loadSocket, sIdLen, 3, 0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
err=send(loadSocket, itemId, idLen, 0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
//=====================================
printf("Please enter download destination path, including FILE NAME.\n");
printf("It's VERY IMPORTANT you use double back slashes!\n");
printf("(Example: c:\\\\temp\\\\file.cpp)\n");
printf("Please enter: ");
gets(loadDir);
download(loadSocket);
} else if (i==2 && strcmp(itemComm, "folder")==0) {
//==========================================
err=send(loadSocket, sIdLen, 3, 0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
err=send(loadSocket, itemId, idLen, 0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
//===============================================================
printf("Please enter a name for your file: ");
gets(uploadFileName);
idLen=strlen(uploadFileName);
_itoa(idLen, sIdLen, 10 );
err=send(loadSocket, sIdLen, 3, 0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
err=send(loadSocket, uploadFileName, idLen,0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
printf("Please enter upload source file directory, including FILE NAME.\n");
printf("It's VERY IMPORTANT you use double back slashes!\n");
printf("Example: c:\\\\temp\\\\file.cpp\n");
printf("Please enter: ");
gets(loadDir);
upload(loadSocket);
}else if (i==0) {
// if the user chooses to quit, 0 is sent to the server side
strcpy(itemId, "0");
err=send(loadSocket, sIdLen, 3, 0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
err=send(loadSocket, itemId, idLen, 0);
if (err==SOCKET_ERROR) {
printf("In send numRead, Client error: %d\n",WSAGetLastError());
exit(10);
}
} else {
printf("Your request cannot be processed. Here are 3 possible reasons:\n");
printf("1. You are asking to download a folder.\n");
printf("2. You are asking to upload to a file.\n");
printf("3. There are some mistake in the record itself.\n");
}
}
//====================================================
// START: Functions for itemRecord Maintainance
//====================================================
void create (void)
{
char itemId[10];
for (int i=1; i<=10; i++) {
_itoa(i, itemId, 10);
items[i].iniRecord(itemId);
}
}
void retrieve (void)
{
FILE *retrieveHandle;
char itemId[10], itemName[50], itemDir[50], itemComm[100];
retrieveHandle=fopen("record.txt", "r");
for (int i=1; i<=10; i++) {
fscanf(retrieveHandle, "%s\n%s\n%s\n%s\n", itemId, itemName, itemDir, itemComm);
items[i].setRecord(itemId, itemName, itemDir, itemComm);
}
fclose(retrieveHandle);
printf("\nFile Retrieved.\n");
}
void display (SOCKET &displaySocket)
{
char command[10];
int i, j=1;
do {
items[j].displayRecord();
currItem=items[j++];
printf("\n0 - quit 1 - download 2 - upload 3 - next record\n");
printf("Please Enter(0 - 3 ): ");
gets(command);
i=atoi(command);
switch (i) {
case 0:
case 1:
case 2: load(i, displaySocket); break;
case 3: break;
default:
printf("Wrong commands used.\n");
break;
}
if(j==11) j=j-10; //always loop the display from item[1] to item[10]
} while (i!=0);
}
//====================================================
// END: Functions for itemRecord Maintainance
//====================================================
|
|