This is the work of the computer network course design, which implements the FTP client.
Use the Winsock2 header file. It is a learning practice of socket programming.
All codes are successfully debugged under vc6.0.
/** Reference rfc959 standard for this program. It can interact with servers that comply with this standard. Only for Windows. */# Include <stdio. h> # include <string. h> # include <stdlib. h>/* system () */# include <winsock2.h> # pragma comment (Lib, "ws2_32.lib ") # define onum 512 # define mnum 512 # define fnum 512 # define ptstruct host {char IP [20]; unsigned short port ;}; socket ts; fd_set readfds; struct timeval; struct host; char renum [4]; char ordertemp [onum]; char order [onum]; char ordercp [onum]; char mess [mnum]; char File [Fnum]; char setpath [fnum]; char setpathf [fnum]; int I, door, R, sys, SETI;/* I for; door switch; r receive num; sys system state; Set set state */char * P;/* strtok */INT printmess (); void input (char ordertemp []); int FTP (); int user (); int pass (); int command (); int list (); socket createdatasocket (); int set (); int RETR (); int stor (); int stor () {char filename [256]; socket Ds; int wi; int R2, R3, R4, bsnum, brnum; FI Le * fp = NULL; Set (); memset (filename, '\ 0', 256); memset (Order,' \ 0', onum); for (I = 5; I <= 200 & ordercp [I]! = '\ 0'; I ++) {order [I-5] = ordercp [I];} strcpy (filename, setpathf); strcat (filename, "\\\\"); strcat (filename, order); memset (Order, '\ 0', onum); strcpy (order, "Type I \ r \ n");/* type I binary type A ASCII */send (TS, order, strlen (Order), 0); Switch (printmess ()) {Case 421: closesocket (TS); sys = 0; return 421; Case 530: closesocket (TS); sys = 0; Return-1; Case 500: Case 501: case 504: Case 226: Return-1; Case 200: break; default: Return-1;} DS = createdatasocket (); If (DS =-1) {return-1;} strcat (ordercp, "\ r \ n"); send (TS, ordercp, strlen (ordercp), 0); Switch (printmess () {Case 421: closesocket (DS ); closesocket (TS); sys = 0; return 421; Case 532: Case 530: closesocket (DS); closesocket (TS); sys = 0; Return-1; Case 450: case 452: Case 553: Case 500: Case 501: closesocket (DS ); Return-1; Case 125: case 150: break; default: closesocket (DS); Return-1;} fp = fopen (filename, "rb"); If (! FP) {printf ("Read File fail! \ N "); closesocket (DS); Return-1;} r2 = 0; R3 = 0; r4 = 0; bsnum = 0; brnum = 0; Wi = 1; while (WI) {memset (file, '\ 0', fnum); r = fread (file, sizeof (char), fnum, FP); If (r = 0) {closesocket (DS); Wi = 0; break;} brnum = brnum + R; R3 = r; printf ("read % 8d bytes! Have read % 16D bytes! \ R ", R, brnum); do {r2 = Send (DS, file, R3, 0); If (R2 = socket_error) {printf (" Send File error! "); Closesocket (DS); Return-1;} bsnum = bsnum + R2; R3 = r3-R2; printf (" Send % 8d bytes! Have sended % 16D bytes! \ R ", R2, bsnum);} while (brnum> bsnum);}/* While */printf (" \ n "); Switch (printmess ()) {Case 425: Case 426: Case 451: Case 551: Case 552: closesocket (DS); fclose (FP); Return-1; Case 250: Case 226: fclose (FP); Return 0; default: Return 0 ;}/ * stor */int retr () {char filename [256]; unsigned long fsize, wfsize; int R2, wi; socket Ds; file * fp = NULL; memset (filename, '\ 0', 256); memset (Order,' \ 0', Onum); for (I = 5; I <= 200 & ordercp [I]! = '\ 0'; I ++) {order [I-5] = ordercp [I];} strcpy (filename, setpathf); strcat (filename, "\\\\"); strcat (filename, order); DS = createdatasocket (); If (DS =-1) {return-1;} memset (order, '\ 0', onum); strcpy (Order, "type I \ r \ n");/* type I binary type A ASCII */send (TS, order, strlen (Order), 0); Switch (printmess () {Case 421: closesocket (DS); closesocket (TS); sys = 0; return 421; Case 530: closeso Cket (DS); closesocket (TS); sys = 0; Return-1; Case 500: Case 501: Case 504: Case 226: closesocket (DS); Return-1; case 200: break; default: closesocket (DS); Return-1;} strcat (ordercp, "\ r \ n"); send (TS, ordercp, strlen (ordercp ), 0); Switch (printmess () {Case 421: closesocket (DS); closesocket (TS); sys = 0; return 421; Case 530: closesocket (DS ); closesocket (TS); sys = 0; Return-1; Case 450: Case 500: Case 501: Case 550: closesocket (DS); Return-1; Case 125: case 150: break; default: closesocket (DS); Return-1 ;} set (); System (setpath); FP = fopen (filename, "WB"); If (! FP) {printf ("Create File fail! \ N "); closesocket (DS); printmess (); Return-1;} Wi = 1; fsize = 0; wfsize = 0; while (WI) {memset (file, '\ 0', fnum); r = Recv (DS, file, fnum, 0); If (r = socket_error) {printf ("file Recv error! \ N "); closesocket (DS); fclose (FP); Return-1;} fsize = fsize + R; If (r = 0) {wi = 0; break;} printf ("receive % 8d bytes! Have received % 16D bytes! \ R ", R, fsize); r2 = fwrite (file, sizeof (char), R, FP); // fflush (FP ); /* The key here */wfsize = wfsize + R2; printf ("write % 8d bytes! Have written % 20d bytes! \ R ", R2, wfsize);}/* While */printf (" \ n "); fflush (FP ); /* here is the key */switch (printmess () {Case 425: Case 426: Case 451: closesocket (DS); fclose (FP); Return-1; Case 250: case 226: closesocket (DS); Wi = 1; while (WI) {If (fclose (FP) = 0) {wi = 0;} return 0; default: closesocket (DS); fclose (FP); Return 0 ;}}/ * RETR () */INT set () {int n, m; n = 3; m = 0; If (strcmp (Order, "set ")! = 0 & SETI = 1) {return 1;} else if (strcmp (Order, "set ")! = 0 & SETI = 0) {memset (setpath, '\ 0', fnum); memset (setpathf,' \ 0', fnum); strcpy (setpath, "md d: \ rhftpdir"); strcpy (setpathf, "d :\\\ rhftpdir"); return 2;} memset (setpath, '\ 0 ', fnum); memset (setpathf, '\ 0', fnum); memset (Order,' \ 0', onum); If (ordercp [5]! = ':') {Printf ("error input! \ N "); Return-1 ;}for (I = 4; I <= 200 & ordercp [I]! = '\ 0'; I ++) {order [I-4] = ordercp [I];} strcpy (setpath, "MD"); for (I = 0; I <= fnum-5 & Order [I]! = '\ 0'; I ++) {If (Order [I] =' \ ') {strcat (setpath ,"\\\\"); N ++; strcat (setpathf, "\\\\"); m ++; continue;} setpathf [I + M] = order [I]; setpath [I + N] = order [I];} printf ("setpath % s \ n", setpath); Seti = 1; return 0 ;} /* Set */INT list () {socket Ds; int wi; DS = createdatasocket (); If (DS =-1) {return-1;} strcat (ordercp, "\ r \ n"); send (TS, ordercp, strlen (ordercp), 0); Switch (printmess ()){ Case 421: closesocket (DS); closesocket (TS); sys = 0; return 421; Case 530: closesocket (DS); closesocket (TS); sys = 0; return-1; Case 450: Case 500: Case 501: Case 502: closesocket (DS); Return-1; Case 125: case 150: break; default: closesocket (DS ); return-1;} Wi = 1; while (WI) {memset (file, '\ 0', fnum); r = Recv (DS, file, fnum-1, 0); If (r = socket_error) {printf ("list file Recv Error! \ N "); closesocket (DS); Return-1;} printf (" % s ", file); If (r = 0) {wi = 0 ;}} switch (printmess () {Case 425: Case 426: Case 451: Case 226: Case 250: closesocket (DS); Return 0; default: closesocket (DS ); return-1 ;}}/* list */socket createdatasocket () {char P1 [5], P2 [5]; unsigned short port; int p1s, P2s; socket Ds; struct sockaddr_in server; memset (Order, '\ 0', onum);/* PASV */strcpy (Order ," PASV \ r \ n "); send (TS, order, strlen (Order), 0); r = printmess (); If (r =-1 | r! = 227) {return-1;} memset (P1, '\ 0', 5); memset (P2,' \ 0', 5); p1s = 0; p2s = 0; for (I = 0, r = 0; I <200 & mess [I]! = '\ 0'; I ++) {If (mess [I] =', ') {r ++; continue;} If (r = 4) {p1 [p1s] = mess [I]; p1s ++; continue;} If (r = 5) {P2 [P2s] = mess [I]; P2s ++; continue;} Port = atoi (P1) * 256 + atoi (P2); printf ("port: % d \ n", Port); server. sin_family = af_inet; server. sin_port = htons (port); server. sin_addr.s_un.s_addr = inet_addr (host. IP); DS = socket (af_inet, sock_stream, ipproto_tcp);/* tcp */If (DS =-1) {Printf ("failed socket () in createdatasocket () \ n"); Return-1;} r = connect (DS, (struct sockaddr *) & server, sizeof (server); If (r = socket_error) {printf ("Connect error in createdatasocket ()! \ N "); closesocket (DS); Return-1;} return Ds;}/* createdatasocket () */INT command () {strcat (ordercp, "\ r \ n"); send (TS, ordercp, strlen (ordercp), 0); Switch (printmess () {Case 421: closesocket (TS ); sys = 0; return 421; Case 221: closesocket (TS); sys = 0; return 221; Case 530: closesocket (TS); sys = 0; return 0; Case 200: case 250: Case 450: Case 550: Case 500: Case 501: Case 502: Return 0; default: Return-1 ;}/ * command */INT pass () {strcat (ordercp, "\ r \ n"); send (TS, ordercp, strlen (ordercp ), 0); Switch (printmess () {Case 421: closesocket (TS); sys = 0; return 421; Case 530: closesocket (TS); sys = 0; return 0; case 500: Case 501: Case 503: Case 202: Return 0; Case 332: SYS = 1; return 0; Case 230: SYS = 3; return 0; default: return-1 ;}}/* Pass */INT user () {If (ordercp [5] = '-') {STRC At (Order, "anonymous \ r \ n"); send (TS, order, strlen (Order), 0);} else {strcat (ordercp, "\ r \ n"); send (TS, ordercp, strlen (ordercp), 0);} switch (printmess () {Case 421: closesocket (TS ); sys = 0; return 421; Case 530: closesocket (TS); sys = 0; return 0; Case 230: SYS = 3; return 0; Case 500: Case 501: case 332: Return 0; Case 331: SYS = 2; return 0; default: Return-1 ;}/ * User */int ftp () {wsad ATA wsadata; struct sockaddr_in serveraddr; If (sys! = 0) {printf ("please Bye first! \ N "); Return 0;} wsastartup (makeword (2, 2), & wsadata);/* bind a socket library */TS = socket (af_inet, sock_stream, ipproto_tcp);/* tcp */If (TS =-1) {printf ("failed socket () \ n"); wsacleanup (); Return-1 ;} memset (host. IP, '\ 0', 20); P = strtok (null, ""); strcpy (host. IP, P); P = strtok (null, ""); If (P = NULL) {Host. port = 21;} else {Host. port = atoi (p);} serveraddr. sin_family = af_inet;/* Host address mark Knowledge */serveraddr. sin_port = htons (host. port);/* port htons 16 */serveraddr. sin_addr.s_un.s_addr = inet_addr (host. IP);/* IP */r = connect (TS, (struct sockaddr *) & serveraddr, sizeof (serveraddr )); /* Send Connection Request */If (r = socket_error) {printf ("Connect error! \ N "); Return-1;} switch (printmess () {Case 220: SYS = 1; return 0; case 120: While (printmess () = 220) {sys = 1; return 0;} Case 421: closesocket (TS); sys = 0; return 421; Case-1: Return-1; default: Return-1 ;}} /* FTP */INT printmess () {int P, N, wi; P = 0; n = 0; Wi = 1; memset (renum, '\ 0 ', 4); fd_zero (& readfds);/* select */fd_set (TS, & readfds); r = select (0, & readfds, null, null ,& Timeval); While (r> 0 & fd_isset (TS, & readfds) & Wi = 1) {memset (mess, '\ 0', mnum ); R = Recv (TS, mess, mnum-1, 0); If (r = socket_error) {printf ("printmess Recv error! \ N "); Return-1 ;}if (P = 0) {strncpy (renum, mess, 4); n = atoi (renum); P = 1 ;} printf ("% s", Mess); fd_zero (& readfds);/* select */fd_set (TS, & readfds); r = select (0, & readfds, null, null, & timeval); If (r = 0) {wi = 0 ;}} return n ;}/ * printmess () */void input (char ordertemp []) {for (I = 0; I <onum; I ++) {ordertemp [I] = getchar (); If (ordertemp [I] = 10) {ordertemp [I] = '\ 0'; break ;}/* 10 enter */} If (ordertemp [0]! = '\ 0') {strcpy (ordercp, ordertemp); P = NULL; P = strtok (ordertemp, ""); strcpy (Order, P ); strlwr (Order) ;}}/* input */INT main () {int wi; Seti = 0; timeval. TV _sec = 0;/* 5000 ms to avoid deadlock */timeval. TV _usec = 500000; printf ("** welcome to use redhaw ftpclient! ** \ N "); sys = 0;/* 0-initial 1-receive user 2-Receive Pass 3-receive other command */Wi = 1; while (WI) {memset (ordertemp, '\ 0', onum); memset (Order,' \ 0', onum); memset (ordercp, '\ 0', onum ); switch (sys) {Case 0: printf ("+ FTP
-By a farmer-