The FTP protocol uses two separate TCP connections, one dedicated to sending FTP commands, and the other dedicated to transmitting data. When a connection is initially established, the server receives a command connection from the client on port 21. When data needs to be transferred (file list, file data, etc.), the client sends a PORT command to the server and enters the listening status, waiting for data connection requests from the server.
First, we use the Appwizard of VC ++ 6.0 to create a dialog box-based application.Program, Named ftpclientdemo. Generate five new classes based on casyncsocket for the program. The main classes are listed here.Code.
Main Code of the ccommandsocket class </P> <p> void ccommandsocket: onreceive (INT nerrorcode) </P> <p >{</P> <p> // This function displays the server's response message in the edit box. </P> <p> char buffer = new char [4096]; </P> <p> memset (buffer,); </P> <p> This-> receive (buffer ); </P> <p> // receives the Response Message </P> <p> messagelist + = buffer; </P> <p> m_returnmessage-> setwindowtext (messagelist ); </P> <p> Delete buffer; </P> <p >}</P> <p> main code of the cfilesocket class </P> <p> void cfileso Cket: onreceive (INT nerrorcode) </P> <p >{</P> <p> // The function writes the received file data to the file. </P> <p> If (file = NULL) </P> <p> {file = new cfile (); </P> <p> file-> open (filename, cfile: modewrite | cfile: modecreate ); </P> <p >}</P> <p> charbuffer = new char [4096]; </P> <p> memset (buffer ); </P> <p> This-> receive (buffer, 4096,0); </P> <p> receivestring = buffer; </P> <p> file-> write (receivestring, receivestring. getlength (); </P> <p> Delete buffer; </P> <p >}</P> <p> main code of the creceivesocket class </P> <p> void creceivesocket: onreceive (INT nerrorcode) </P> <p >{</P> <p> // receives the file list message from the server. </P> <p> cstring receivestring, temp; </P> <p> charbuffer = new char [4096]; </P> <p> memset (buffer ); </P> <p> This-> receive (buffer, 4096, 0); // receives messages </P> <p> receivestring + = buffer; </P> <p> Delete buffer; </P> <p> // separates the file list from the received message string, and displayed in the list box </P> <p> while (! Receivestring. isempty () </P> <p> {int P = receivestring. Find ("\ r \ n"); </P> <p> If (P! =-1) </P> <p> {temp = receivestring. left (p); </P> <p> receivestring = receivestring. right (receivestring. getlength ()-P-2); </P> <p> displaymessage-> addstring (temp ); </P> <p >}</P> <p> main cportsocket Code </P> <p> void cportsocket:: onaccept (INT nerrorcode) </P> <p >{</P> <p> // select the corresponding data connection class based on different labels, to accept data connection requests from the server </P> <p> If (flag = listfile) </P> <p> // if the program requires a list of directories, use the creceivesocket class </P> <p> {datas Ocket = new creceivesocket (filelist); </P> <p> This-> Accept (datasocket ); </P> <p >}</P> <p> else if (flag = download) </P> <p> // if the program requires file download, the cfilesocket class object is generated </P> <p> {filesocket = new cfilesocket (filename); </P> <p> This-> Accept (filesocket ); </P> <p >}</P> <p> main code of cftpclient-demodlg in the Main Dialog Box </P> <p> void cftpclientdemodlg:: onfilelist () </P> <p> // responds to the "file list" button and List Directory </P> <p> {cstring temp; </P> <p> If (con Trolsocket = NULL) </P> <p >{</P> <p> // connect to the FTP server </P> <p> controlsocket = new ccommandsocket (& amp; & amp; m_returnmessage); </P> <p> controlsocket-> Create (); </P> <p> m_server.getwindowtext (temp ); </P> <p> controlsocket-> connect (temp, 21 ); </P> <p> // the FTP server receives connections on port 21 </P> <p >}</P> <p> m_user.getwindowtext (temp ); </P> <p> temp = "user" + temp + "\ r \ n"; </P> <p> controlsocket-> send (temp, temp. getlength (), 0); </P> <p>/ /Run the USER command to verify the user </P> <p> m_pass.getwindowtext (temp ); // m_pass is the corresponding control in the "password" edit box </P> <p> temp = "pass" + temp + "\ r \ n "; </P> <p> controlsocket-> send (temp, temp. getlength (), 0); </P> <p> // send the PASS command to verify the password </P> <p> lisentport (listfile ); </P> <p> // The data connection object is the directory list </P> <p> controlsocket-> send ("list \ r \ n", 7, 0); </P> <p> // issue the LIST Command, requiring the List Directory </P> <p >}</P> <p> void cftpclientdemodlg :: ondownload () </P> <p> // download an object </P> <p >{</P> <p> CST Ring string; </P> <p> lisentport (download ); </P> <p> // obtain the name of the file to be downloaded </P> <p> m_localfile.getwindowtext (string ); </P> <p> // m_localfile is the corresponding control of the "file name" edit box </P> <p> string = "retr" + String + "\ r \ n"; </P> <p> controlsocket-> send (string, String. getlength (), 0); </P> <p> // run the RETR command to download the file </P> <p >}</P> <p> void cftpclientdemodlg:: lisentport (uint flag) </P> <p >{</P> <p> // select different data connection objects as required </P> <p> If (lisentsocket! = NULL) </P> <p> // clear lisentsocket </P> <p> {lisentsocket-> close (); </P> <p> Delete lisentsocket; </P> <p> lisentsocket = NULL; </P> <p >}</P> <p> If (flag = listfile) </P> <p> // if it is a directory list data connection object </P> <p> {lisentsocket = new cportsocket (listfile ); </P> <p> lisentsocket-> setlistbox (& amp; m_filelist ); </P> <p> // upload the list box to the clisentsocket class </P> <p >}</P> <p> else if (flag = download) </P> <p> // if it is a file transfer data connection object </P> <p> {CSTR Ing string; </P> <p> m_localfile.getwindowtext (string); </P> <p> lisentsocket = new cportsocket (download ); </P> <p> lisentsocket-> setfilename (string ); </P> <p> // upload the file name to the clisentsocket class </P> <p >}</P> <p> lisentsocket-> Create (); </P> <p> // establish a socket and listen to it. Wait for the FTP server to connect to the Data. </P> <p> lisentsocket-> listen (); </P> <p> // obtain the IP address and listening port of the Data Connection socket, and use them as parameters of the port command </P> <p> sockaddr_in listing_address, control_address; </P> <p> Int addr_size; </P> <p> addr_size = sizeof (listing_address); </P> <p> lisentsocket-> getsockname (sockaddr) & amp; listing_address, & amp; addr_size); // <br/> obtain the IP address </P> <p> controlsocket-> getsockname (sockaddr) & amp; control_address, & amp; addr_size);/<br/>/fetch port </P> <p> unsigned char Port = (unsigned char) & amp; (listing_address.sin_port); </P> <p> unsigned char host = (unsigned ch AR) & amp; (control_address.sin_addr); </P> <p> cstring strbuffer; </P> <p> strbuffer. format ("port % I, % I \ r \ n", (INT) host [0], (INT) host [1], (<br/> INT) host [2], (INT) host [3], (INT) Port [0], (INT) port [1]); </P> <p> controlsocket-> send (strbuffer, strbuffer. getlength (), 0); </P> <p> // send the PORT command, data Connection </P> <p >}</P> <p> the above Code runs on VC ++ 6.0 and Windows 98. <Br/>