返回   cpper编程论坛 > 技术杂烩
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

技术杂烩 找不到地方的技术问题?这里!

回复
 
LinkBack 主题工具 显示模式
  #1 (permalink)  
旧 2004-12-10
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,563
文章: 6
cat 正向着好的方向发展
默认 某网络实验教材的FtpClient

注:我记得网上下来的这个版本无法直接编译通过。我照抄(稍许过滤一下)的那个好像可以。此处为原版
代码:
// FTPClient.h: interface for the CFTPClient class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_FTPCLIENT_H__C10266B9_50F4_11D5_B587_00E04C39B036__INCLUDED_) #define AFX_FTPCLIENT_H__C10266B9_50F4_11D5_B587_00E04C39B036__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "ftpsocket.h" class CFTPClient { protected: BOOL ReadStr2(); int ReadStr(); BOOL WriteStr(CString outputstring); BOOL ConnectRemote(CString serverhost,int serverport); CArchive* m_pCtrlRxarch; CArchive* m_pCtrlTxarch; CSocketFile* m_pCtrlsokfile; CFTPSocket* m_Ctrlsok; int m_fc; CString m_retmsg; CByteArray m_buf; CString m_strLine; public: // CMessageDlg m_dlgMsg; Disconnect(); BOOL MoveFile(CString remotefile, CString localfile,BOOL get,BOOL pasv = FALSE); BOOL List(); BOOL FTPcommand(CString command); BOOL Logon(CString hostname,int hostport,CString username, CString password);// CString acct, CString fwhost,CString fwusername, CString fwpassword,int fwport,int logontype); void Receive(); CFTPClient(CFtpDownloadDlg *pDoc); virtual ~CFTPClient(); protected: BOOL GetLine(int& ndx); void ProcessList(); CFtpDownloadDlg* m_pDoc; }; #endif // !defined(AFX_FTPCLIENT_H__C10266B9_50F4_11D5_B587_00E04C39B036__INCLUDED_)
代码:
// FTPClient.cpp: implementation of the CFTPClient class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "FtpDownload.h" #include "FTPClient.h" #include "ftpdownloaddlg.h" #include "ftpsocket.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #define SAFEDELTE(x) if(x!=NULL){delete x;x = NULL;} ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CFTPClient::CFTPClient(CFtpDownloadDlg *pDoc) { m_pCtrlRxarch = NULL; m_pCtrlTxarch = NULL; m_pCtrlsokfile = NULL; m_Ctrlsok = NULL; m_pDoc = pDoc; } CFTPClient::~CFTPClient() { SAFEDELTE(m_pCtrlRxarch); SAFEDELTE(m_pCtrlTxarch); SAFEDELTE(m_pCtrlsokfile); SAFEDELTE(m_Ctrlsok); } void CFTPClient::Receive() { } BOOL CFTPClient::Logon(CString hostname, int hostport, CString username, CString password)//, CString acct, CString fwhost, CString fwusername, CString fwpassword, int fwport, int logontype) { // if(m_dlgMsg.m_hWnd == NULL){ // m_dlgMsg.Create(AfxGetMainWnd()); // } // else // m_dlgMsg.ShowWindow(SW_SHOW); int port,logonpoint=0; const int LO=-2, ER=-1; CString buf,temp; const int NUMLOGIN=9; // currently supports 9 different login sequences int logonseq[100] = {0,LO,3, 1,LO,6, 2,LO,ER}; // this array stores all of the logon sequences for the various firewalls // in blocks of 3 nums. 1st num is command to send, 2nd num is next point in logon sequence array // if 200 series response is rec'd from server as the result of the command, 3rd num is next // point in logon sequence if 300 series rec'd // no firewall temp=hostname; port=hostport; if(hostport!=21) hostname.Format(hostname+":%d",hostport); // add port to hostname (only if port is not 21) if(!ConnectRemote(temp,port)) return false; if(!FTPcommand("")) return FALSE; // get initial connect msg off server // go through appropriate logon procedure while(1) { switch(logonseq[logonpoint]) { case 0: temp="USER "+username; break; case 1: temp="PASS "+password; break; // case 2: // temp="ACCT "+acct; // break; // case 3: // temp="USER "+fwusername; // break; // case 4: // temp="PASS "+fwpassword; // break; // case 5: // temp="SITE "+hostname; // break; // case 6: // temp="USER "+username+"@"+hostname; // break; // case 7: // temp="OPEN "+hostname; // break; // case 8: // temp="USER "+fwusername+"@"+hostname; // break; // case 9: // temp="USER "+username+"@"+hostname+" "+fwusername; // break; // case 10: // temp="USER "+username+"@"+fwusername+"@"+hostname; // break; // case 11: // temp="PASS "+password+"@"+fwpassword; // break; } // send command, get response if(!WriteStr(temp)) return FALSE; if(!ReadStr()) return FALSE; // only these responses are valid if(m_fc!=2 && m_fc!=3) return FALSE; logonpoint=logonseq[logonpoint+m_fc-1]; //get next command from array switch(logonpoint) { case ER: // ER means summat has gone wrong m_retmsg.LoadString(IDS_FTPMSG1); return FALSE; case LO: // LO means we're fully logged on return TRUE; } } } BOOL CFTPClient::ConnectRemote(CString serverhost, int serverport) { SAFEDELTE(m_pCtrlRxarch); SAFEDELTE(m_pCtrlTxarch); SAFEDELTE(m_pCtrlsokfile); SAFEDELTE(m_Ctrlsok); if(m_Ctrlsok == NULL) m_Ctrlsok = new CFTPSocket; if( !(m_Ctrlsok->Create())) return FALSE; if(!(m_Ctrlsok->Connect(serverhost,serverport))) return FALSE; if(!(m_pCtrlsokfile=new CSocketFile(m_Ctrlsok))) return FALSE; if(!(m_pCtrlRxarch=new CArchive(m_pCtrlsokfile,CArchive::load))) return FALSE; if(!(m_pCtrlTxarch=new CArchive(m_pCtrlsokfile,CArchive::store))) return FALSE; return TRUE; } BOOL CFTPClient::WriteStr(CString outputstring) { TRY { m_pCtrlTxarch->WriteString(outputstring+"\r\n"); m_pCtrlTxarch->Flush(); } CATCH(CException,e) { return FALSE; } END_CATCH return TRUE; } int CFTPClient::ReadStr() { int retcode; if(!ReadStr2()) return FALSE; if(m_retmsg.GetLength() < 4 || m_retmsg.GetAt(3) != '-') return TRUE; //AfxMessageBox(m_retmsg); retcode=atol(m_retmsg); while(1) { //handle multi-line server responses if(m_retmsg.GetLength() > 3 && (m_retmsg.GetAt(3) == ' ' && atol(m_retmsg) == retcode)) return TRUE; if(!ReadStr2()) return FALSE; } } BOOL CFTPClient::ReadStr2() { TRY { if(!m_pCtrlRxarch->ReadString(m_retmsg)) { return FALSE; } } CATCH(CException,e) { return FALSE; } END_CATCH if(m_retmsg.GetLength() > 0) m_fc = m_retmsg.GetAt(0)-48; // m_dlgMsg.TextOut(m_retmsg); // get 1st digit of the return code (indicates primary result) return TRUE; } BOOL CFTPClient::FTPcommand(CString command) { if(command != "" && !WriteStr(command)) return FALSE; if((!ReadStr()) || (m_fc != 2)) return FALSE; return TRUE; } BOOL CFTPClient::List() { CString lhost,temp,rhost; UINT localsock,i; CFile datafile; CSocket sockSrvr; CAsyncSocket datachannel; int num, sum; const int BUFSIZE = 4096; DWORD lpArgument=0; m_buf.RemoveAll(); m_buf.SetSize(BUFSIZE); if(!FTPcommand("TYPE I")) return FALSE; // request BINARY mode m_retmsg.LoadString(IDS_FTPMSG6); // get the local IP address off the control channel socket if(!m_Ctrlsok->GetSockName(lhost,localsock)) return FALSE;; while(1) { // convert returned '.' in ip address to ',' if((i=lhost.Find("."))==-1) break; lhost.SetAt(i,','); } // create listen socket (let MFC choose the port) & start the socket listening if((!sockSrvr.Create(0, SOCK_STREAM, NULL)) || (!sockSrvr.Listen())) return FALSE; if(!sockSrvr.GetSockName(temp,localsock)) return FALSE;// get the port that MFC chose // convert the port number to 2 bytes + add to the local IP lhost.Format(lhost+",%d,%d", localsock / 256, localsock % 256); if(!FTPcommand("PORT "+lhost)) return FALSE;// send PORT cmd to server if(!WriteStr("LIST") ) return FALSE; if(!ReadStr()) return FALSE; // get response to RETR/STOR command if(!sockSrvr.Accept(datachannel)) return FALSE; // if !PASV accept inbound data connection from server // we're connected & ready to do the data transfer, so set blocking mode on data channel socket if((!datachannel.AsyncSelect(0)) || (!datachannel.IOCtl(FIONBIO,&lpArgument))) { m_retmsg.LoadString(IDS_FTPMSG6); return FALSE; } sum = 0; while(1) { // move data from/to server TRY { if(!(num = datachannel.Receive(m_buf.GetData() + sum, BUFSIZE, 0)) || num == SOCKET_ERROR) break; // (EOF||network error) TRACE("Received :%d\n", num); Sleep(0); sum += num; m_buf.SetSize(sum + BUFSIZE); } CATCH (CException,e) { m_retmsg.LoadString(IDS_FTPMSG5); return FALSE; } END_CATCH } datachannel.Close(); ProcessList(); if(!FTPcommand("")) return FALSE; // check transfer outcome msg from server return TRUE; // oh goody it worked. } void CFTPClient::ProcessList() { int ndx = 0; while(GetLine(ndx)) { (m_pDoc->m_ListFile).AddString(m_strLine); } } BOOL CFTPClient::GetLine(int& ndx) { m_strLine.Empty(); int nBytes = m_buf.GetSize(); BOOL bLine = FALSE; while ( bLine == FALSE && ndx < nBytes ) { char ch = (char)(m_buf.GetAt( ndx )); switch( ch ) { case '\n': // end-of-line bLine = TRUE; break; default: // other.... m_strLine += ch; break; } ++ndx; } m_strLine = m_strLine.Left(m_strLine.GetLength() - 1); return bLine; } BOOL CFTPClient::MoveFile(CString remotefile, CString localfile, BOOL get, BOOL pasv) { CString lhost,temp,rhost; UINT localsock,serversock,i,j; CFile datafile; CSocket sockSrvr; CAsyncSocket datachannel; int num,numread,numsent; const int BUFSIZE=4096; char cbuf[BUFSIZE]; DWORD lpArgument=0; // open local file if(!datafile.Open(localfile,(get ? CFile::modeWrite | CFile::modeCreate : CFile::modeRead))) { m_retmsg.LoadString(IDS_FTPMSG4); return FALSE; } if(!FTPcommand("TYPE I")) return FALSE; // request BINARY mode if(pasv) { // set up a PASSIVE type file transfer if(!FTPcommand("PASV")) return FALSE; // extract connect port number and IP from string returned by server if((i=m_retmsg.Find("("))==-1 || (j=m_retmsg.Find(")"))==-1) return FALSE; temp = m_retmsg.Mid(i+1,(j-i)-1); i=temp.ReverseFind(','); serversock=atol(temp.Right(temp.GetLength()-(i+1))); //get ls byte of server socket temp=temp.Left(i); i=temp.ReverseFind(','); serversock += 256*atol(temp.Right(temp.GetLength()-(i+1))); // add ms byte to server socket rhost=temp.Left(i); while(1) { // convert commas to dots in IP if((i=rhost.Find(","))==-1) break; rhost.SetAt(i,'.'); } } else { // set up a ACTIVE type file transfer m_retmsg.LoadString(IDS_FTPMSG6); // get the local IP address off the control channel socket if(!m_Ctrlsok->GetSockName(lhost,localsock)) return FALSE;; while(1) { // convert returned '.' in ip address to ',' if((i=lhost.Find("."))==-1) break; lhost.SetAt(i,','); } // create listen socket (let MFC choose the port) & start the socket listening if((!sockSrvr.Create(0,SOCK_STREAM,NULL)) || (!sockSrvr.Listen())) return FALSE; if(!sockSrvr.GetSockName(temp,localsock)) return FALSE;// get the port that MFC chose // convert the port number to 2 bytes + add to the local IP lhost.Format(lhost+",%d,%d",localsock/256,localsock%256); if(!FTPcommand("PORT "+lhost)) return FALSE;// send PORT cmd to server } // send RETR/STOR command to server if(!WriteStr(( get ? "RETR " : "STOR ") + remotefile)) return FALSE; if(pasv) {// if PASV create the socket & initiate outbound data channel connection if(!datachannel.Create()) { m_retmsg.LoadString(IDS_FTPMSG6); return FALSE; } datachannel.Connect(rhost,serversock); // attempt to connect asynchronously (server will tell us if/when we're connected) } if(!ReadStr() || m_fc!=1) return FALSE; // get response to RETR/STOR command if(!pasv&&!sockSrvr.Accept(datachannel)) return FALSE; // if !PASV accept inbound data connection from server // we're connected & ready to do the data transfer, so set blocking mode on data channel socket if((!datachannel.AsyncSelect(0)) || (!datachannel.IOCtl(FIONBIO,&lpArgument))) { m_retmsg.LoadString(IDS_FTPMSG6); return FALSE; } while(1) { // move data from/to server & read/write local file TRY { if(get) { if(!(num=datachannel.Receive(cbuf,BUFSIZE,0)) || num==SOCKET_ERROR) break; // (EOF||network error) else datafile.Write(cbuf,num); } else { if(!(numread=datafile.Read(cbuf,BUFSIZE))) break; //EOF if((numsent=datachannel.Send(cbuf,numread,0))==SOCKET_ERROR) break; // if we sent fewer bytes than we read from file, rewind file pointer if(numread != numsent) datafile.Seek(numsent-numread,CFile::current); } } CATCH (CException,e) { m_retmsg.LoadString(IDS_FTPMSG5); return FALSE; } END_CATCH } datachannel.Close(); datafile.Close(); if(!FTPcommand("")) return FALSE; // check transfer outcome msg from server AfxMessageBox("文件下载成功!"); return TRUE; // oh goody it worked. } CFTPClient::Disconnect() { if(m_Ctrlsok != NULL){ m_Ctrlsok->Close(); } SAFEDELTE(m_pCtrlRxarch); SAFEDELTE(m_pCtrlTxarch); SAFEDELTE(m_pCtrlsokfile); SAFEDELTE(m_Ctrlsok); }
由于耦合性和循环依赖,没有整个工程是不行的,工程文件也发上来:
上传的附件
文件类型: rar _______ftp__________.rar (89.0 KB, 9 次查看)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #2 (permalink)  
旧 2004-12-11
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,138
文章: 20
polyrandom 正向着好的方向发展
默认

能否把过滤好的也放出?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #3 (permalink)  
旧 2004-12-11
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,563
文章: 6
cat 正向着好的方向发展
默认

……过滤好的啊,结构上没有本质改变,只是可以编译运行了而已。
上传的附件
文件类型: rar ftpdownload.rar (17.5 KB, 5 次查看)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用



所有时间均为格林尼治时间 +9。现在的时间是 08:58 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2009,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0