FTPSend.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. /*/////////////////////////////////////////////////////////////////////
  2. FTPSend.cpp (c) GDI 1999
  3. V1.0.0 (10/4/99)
  4. Phil Anderson. philip@gd-ind.com
  5. Simple FTP client functionality. If you have any problems with it,
  6. please tell me about them (or better still e-mail me the fixed
  7. code). Please feel free to use this code however you wish, although
  8. if you make changes please put your name in the source & comment what
  9. you did.
  10. Nothing awesome going on here at all (all sockets are used in
  11. synchronous blocking mode), but it does the following
  12. things WinInet doesn't seem to:
  13. * Supports loads of different firewalls (I think, I don't
  14. have access to all types so they haven't all been fully
  15. tested yet)
  16. * Allows you to execute any command on the FTP server
  17. * Adds 10K to your app install rather than 1Mb #;-)
  18. Functions return TRUE if everything went OK, FALSE if there was an,
  19. error. A message describing the outcome (normally the one returned
  20. from the server) will be in m_retmsg on return from the function.
  21. There are a few error msgs in the app's string table that you'll
  22. need to paste into your app, along with this file & FTPSend.h
  23. If you created your app without checking the "Use Windows Sockets"
  24. checkbox in AppWizard, you'll need to add the following bit of code
  25. to you app's InitInstance()
  26. if(!AfxSocketInit())
  27. {
  28. AfxMessageBox("Could not initialize Windows Sockets!");
  29. return FALSE;
  30. }
  31. To use:
  32. 1/ Create an object of CFTPSend.
  33. 2/ Use LogOnToServer() to connect to the server. Any arguments
  34. not used (e.g. if you're not using a firewall), pass an empty
  35. string or zero for numeric args. You must pass a server port
  36. number, use the FTP default of 21 if you don't know what it is.
  37. 3/ Use MoveFile() to upload/download a file, 1st arg is local file
  38. path, 2nd arg is remote file path, 3rd arg is TRUE for a PASV
  39. connection (required by some firewalls), FALSE otherwise, 4th arg
  40. is TRUE to upload, FALSE to download file. MoveFile only works in
  41. synchronous mode (ie the function will not return 'till the transfer
  42. is finished). File transfers are always of type BINARY.
  43. 4/ You can use FTPcommand() to execute FTP commands (eg
  44. FTPcommand("CWD /home/mydir") to change directory on the server),
  45. note that this function will return FALSE unless the server response
  46. is a 200 series code. This should work fine for most FTP commands,
  47. otherwise you can use WriteStr() and ReadStr() to send commands &
  48. interpret the response yourself. Use LogOffServer() to disconnect
  49. when done.
  50. /////////////////////////////////////////////////////////////////////*/
  51. #include "stdafx.h"
  52. #include "CPhotoFTPSend.h"
  53. #include "FTPSend.h"
  54. #include "CPhotoFTPSendDlg.h"
  55. #include "MyLock.h"
  56. #include "Shlwapi.h"
  57. #ifdef _DEBUG
  58. #undef THIS_FILE
  59. static char THIS_FILE[]=__FILE__;
  60. #define new DEBUG_NEW
  61. #endif
  62. extern void WriteLogin(CString str);
  63. extern CCPhotoFTPSendDlg *g_pMainWnd;
  64. extern BOOL g_bActive[MAX_THREAD];
  65. extern BOOL g_check1;
  66. extern CString g_mainpath;
  67. //////////////////////////////////////////////////////////////////////
  68. // Construction/Destruction
  69. //////////////////////////////////////////////////////////////////////
  70. CFTPSend::CFTPSend()
  71. {
  72. m_pCtrlsokfile=NULL;
  73. m_pCtrlTxarch=NULL;
  74. m_pCtrlRxarch=NULL;
  75. m_Ctrlsok=NULL;
  76. m_bStop=NULL;
  77. m_pasved=0;
  78. }
  79. CFTPSend::~CFTPSend()
  80. {
  81. CloseControlChannel();
  82. if(m_pasved)
  83. {
  84. // datachannel.Close();m_pasved=0;
  85. }
  86. }
  87. //////////////////////////////////////////////////////////////////////
  88. // Public Functions
  89. //////////////////////////////////////////////////////////////////////
  90. // function to connect & log on to FTP server
  91. //BOOL CFTPSend2::LogOnToServer(CString hostname,int hostport,CString username, CString password)
  92. BOOL CFTPSend::LogOnToServer(CString hostname,int hostport,CString username, CString password)
  93. {
  94. CString acct="";
  95. CString fwhost="";
  96. CString fwusername="";
  97. CString fwpassword="";
  98. int fwport=21;
  99. int logontype=0;
  100. int port,logonpoint=0;
  101. const int LO=-2, ER=-1;
  102. CString buf,temp;
  103. //登陆方式数目
  104. const int NUMLOGIN=9;
  105. //登陆方式数组
  106. int logonseq[NUMLOGIN][100] =
  107. {
  108. {0,LO,3, 1,LO,6, 2,LO,ER}, // no firewall
  109. {3,6,3, 4,6,ER, 5,ER,9, 0,LO,12, 1,LO,15, 2,LO,ER}, // SITE hostname
  110. {3,6,3, 4,6,ER, 6,LO,9, 1,LO,12, 2,LO,ER}, // USER after logon
  111. {7,3,3, 0,LO,6, 1,LO,9, 2,LO,ER}, //proxy OPEN
  112. {3,6,3, 4,6,ER, 0,LO,9, 1,LO,12, 2,LO,ER}, // Transparent
  113. {6,LO,3, 1,LO,6, 2,LO,ER}, // USER with no logon
  114. {8,6,3, 4,6,ER, 0,LO,9, 1,LO,12, 2,LO,ER}, //USER fireID@remotehost
  115. {9,ER,3, 1,LO,6, 2,LO,ER}, //USER remoteID@remotehost fireID
  116. {10,LO,3, 11,LO,6, 2,LO,ER} // USER remoteID@fireID@remotehost
  117. };
  118. //连接方式无效
  119. if(logontype<0||logontype>=NUMLOGIN)
  120. return FALSE;
  121. //确定直接连接还是通过防火墙连接
  122. if(!logontype)
  123. {
  124. temp=hostname;
  125. port=hostport;
  126. }
  127. else
  128. {
  129. temp=fwhost;
  130. port=fwport;
  131. }
  132. if(hostport!=21)
  133. hostname.Format("%s:%d", hostname, hostport);
  134. //打开控制连接
  135. if(!OpenControlChannel(temp,port))
  136. return false;
  137. //获取初始的服务器信息
  138. if(!FTPcommand(""))
  139. return FALSE;
  140. // 测试连接,便于选择适合的登陆方式
  141. while(1)
  142. {
  143. switch(logonseq[logontype][logonpoint])
  144. {
  145. case 0:
  146. temp="USER "+username;
  147. break;
  148. case 1:
  149. temp="PASS "+password;
  150. break;
  151. case 2:
  152. temp="ACCT "+acct;
  153. break;
  154. case 3:
  155. temp="USER "+fwusername;
  156. break;
  157. case 4:
  158. temp="PASS "+fwpassword;
  159. break;
  160. case 5:
  161. temp="SITE "+hostname;
  162. break;
  163. case 6:
  164. temp="USER "+username+"@"+hostname;
  165. break;
  166. case 7:
  167. temp="OPEN "+hostname;
  168. break;
  169. case 8:
  170. temp="USER "+fwusername+"@"+hostname;
  171. break;
  172. case 9:
  173. temp="USER "+username+"@"+hostname+" "+fwusername;
  174. break;
  175. case 10:
  176. temp="USER "+username+"@"+fwusername+"@"+hostname;
  177. break;
  178. case 11:
  179. temp="PASS "+password+"@"+fwpassword;
  180. break;
  181. }
  182. //发送命令
  183. if(!WriteStr(temp))
  184. return FALSE;
  185. if(!ReadStr())
  186. return FALSE;
  187. if(m_fc!=2&&m_fc!=3)
  188. return FALSE;
  189. //获取下一条命令
  190. logonpoint=logonseq[logontype][logonpoint+m_fc-1];
  191. switch(logonpoint)
  192. {
  193. //登陆错误
  194. case ER:
  195. m_retmsg.LoadString(IDS_FTPMSG1);
  196. return FALSE;
  197. //完全登陆
  198. case LO:
  199. return TRUE;
  200. }
  201. }
  202. }
  203. // function to log off & close connection to FTP server
  204. void CFTPSend::LogOffServer()
  205. {
  206. WriteStr("QUIT");
  207. CloseControlChannel();
  208. }
  209. // function to execute commands on the FTP server
  210. BOOL CFTPSend::FTPcommand(CString command) {
  211. if(command!=""&&!WriteStr(command)) return FALSE;
  212. if((!ReadStr())||(m_fc!=2)) return FALSE;
  213. return TRUE;
  214. }
  215. void LoadImageFromBuf(Image **img, BYTE *pData, DWORD leng)
  216. {
  217. try
  218. {
  219. if(pData==NULL)return;
  220. if(*img)delete *img;
  221. *img=NULL;
  222. // Allocate global memory on which to create stream
  223. HGLOBAL m_hMem = GlobalAlloc(GMEM_MOVEABLE, leng);
  224. if(m_hMem==NULL)return;
  225. BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
  226. memcpy(pmem,pData,leng);
  227. IStream* pstm;
  228. CreateStreamOnHGlobal(m_hMem,TRUE,&pstm);
  229. // load from stream
  230. *img=Gdiplus::Image::FromStream(pstm);
  231. // free/release stuff
  232. GlobalUnlock(m_hMem);
  233. pstm->Release();
  234. }
  235. catch(...)
  236. {
  237. }
  238. }
  239. void LoadImageFromBuf(Image **img, CString path)
  240. {
  241. try
  242. {
  243. CFile fp;
  244. if(fp.Open (path, CFile::modeRead))
  245. {
  246. DWORD leng=fp.GetLength ();
  247. BYTE *pData=new BYTE[leng];
  248. fp.Read (pData, leng);
  249. fp.Close ();
  250. LoadImageFromBuf(img, pData, leng);
  251. delete []pData;
  252. }
  253. }
  254. catch(...)
  255. {
  256. }
  257. }
  258. int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
  259. {
  260. UINT num = 0; // number of image encoders
  261. UINT size = 0; // size of the image encoder array in bytes
  262. ImageCodecInfo* pImageCodecInfo = NULL;
  263. GetImageEncodersSize(&num, &size);
  264. if(size == 0)
  265. return -1; // Failure
  266. pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
  267. if(pImageCodecInfo == NULL)
  268. return -1; // Failure
  269. GetImageEncoders(num, size, pImageCodecInfo);
  270. for(UINT j = 0; j < num; ++j)
  271. {
  272. if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
  273. {
  274. *pClsid = pImageCodecInfo[j].Clsid;
  275. free(pImageCodecInfo);
  276. return j; // Success
  277. }
  278. }
  279. free(pImageCodecInfo);
  280. return -1; // FailureFailure
  281. }
  282. void SaveImageToFile(Image *img, CString path)
  283. {
  284. try
  285. {
  286. if(img==NULL)return;
  287. CLSID encoderClsid;
  288. BSTR bstr= path.AllocSysString();
  289. path.MakeLower ();
  290. if(path.Right (3)=="bmp")
  291. {
  292. GetEncoderClsid(L"image/bmp", &encoderClsid);
  293. img->Save(bstr, &encoderClsid, NULL);
  294. }
  295. else if(path.Right (3)=="png")
  296. {
  297. GetEncoderClsid(L"image/png", &encoderClsid);
  298. img->Save(bstr, &encoderClsid, NULL);
  299. }
  300. else// if(path.Right (3)=="jpg")
  301. {
  302. GetEncoderClsid(L"image/jpeg", &encoderClsid);
  303. EncoderParameters encoderParameters;
  304. ULONG quality;
  305. encoderParameters.Count = 1;
  306. encoderParameters.Parameter[0].Guid = EncoderQuality;
  307. encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
  308. encoderParameters.Parameter[0].NumberOfValues = 1;
  309. // Save the image as a JPEG with quality level 100.
  310. quality = 80;
  311. encoderParameters.Parameter[0].Value = &quality;
  312. img->Save(bstr, &encoderClsid, &encoderParameters);
  313. }
  314. SysFreeString(bstr);
  315. }
  316. catch(...)
  317. {
  318. }
  319. }
  320. void RectFitDes(int width, int height, CRect &rc)
  321. {
  322. try
  323. {
  324. if(width==0 || height==0)return;
  325. if(rc.Width ()==0 || rc.Height ()==0)return;
  326. float fscale=(float)width/(float)height;
  327. float rcscale=((float)rc.Width ())/((float)rc.Height ());
  328. int rcwid=rc.Width ();
  329. int rchei=rc.Height ();
  330. int dt=0;
  331. if(rcscale<fscale)
  332. {
  333. dt=(rchei-rcwid/fscale)/2;
  334. rc.top+=dt;
  335. rc.bottom-=dt;
  336. }
  337. else
  338. {
  339. dt=(rcwid-rchei*fscale)/2;
  340. rc.left +=dt;
  341. rc.right-=dt;
  342. }
  343. }
  344. catch(...)
  345. {
  346. }
  347. }
  348. CString g_failstr;
  349. // function to upload/download files
  350. int CFTPSend::MoveFile(CString remotefile, CString localfile, BOOL blast)
  351. {
  352. try
  353. {
  354. g_failstr="";
  355. BOOL pasv=1;
  356. CString lhost,temp,rhost;
  357. UINT localsock,serversock,i,j;
  358. CFile datafile;
  359. //侦听服务器的连接
  360. CSocket sockSrvr;
  361. //数据连接通道
  362. CAsyncSocket datachannel;
  363. //接收、发送字节
  364. int num,numread,numsent;
  365. //缓冲区大小
  366. const int BUFSIZE=4096;
  367. //缓冲区
  368. char cbuf[BUFSIZE];
  369. DWORD lpArgument=0;
  370. DWORD fileleng=0;
  371. DWORD sended=0;
  372. int m_check1=g_check1;
  373. // WriteLogin("开始上传!"+localfile.Right (localfile.GetLength ()-localfile.ReverseFind ('\\')-1) );
  374. if( (!m_ziptype.IsEmpty ()) && blast==0 )
  375. {
  376. // WriteLogin("压缩!");
  377. m_check1=0;
  378. ::CreateDirectory (g_mainpath+"\\temp", NULL);
  379. CString timestamp=CTime::GetCurrentTime ().Format ("%Y%m%d%H%M%S");
  380. CString newpath;
  381. newpath.Format ("%s\\temp\\%s%d.jpg", g_mainpath,timestamp, m_pos);
  382. Image *img=NULL;
  383. ::LoadImageFromBuf (&img, localfile);
  384. if(img==NULL)
  385. {
  386. // WriteLogin("载入照片失败,不压缩传送!");
  387. g_failstr="载入照片失败";
  388. // return 0;
  389. }
  390. else
  391. {
  392. // WriteLogin("载入图片成功!");
  393. if(img->GetWidth())
  394. {
  395. int newsize=atoi(m_ziptype);
  396. CRect rc(0,0,newsize,newsize);
  397. RectFitDes(img->GetWidth(), img->GetHeight(), rc);
  398. Image *simg= img->GetThumbnailImage(rc.Width (), rc.Height (), NULL, NULL);
  399. Graphics graphic(simg);//防止GetThumbnailImage影响质量
  400. graphic.DrawImage(img, 0,0,simg->GetWidth(), simg->GetHeight() );
  401. delete img;
  402. ::SaveImageToFile(simg, newpath);
  403. delete simg;
  404. localfile=newpath;
  405. }
  406. else
  407. {
  408. // WriteLogin("载入照片失败,不压缩传送!");
  409. g_failstr="载入照片失败";
  410. // return 0;
  411. }
  412. }
  413. }
  414. if(1)
  415. {
  416. MyLock lock("g_bActiveaccess");
  417. g_bActive[m_pos]=1;
  418. }
  419. DWORD tick=::GetTickCount ();
  420. if(blast)
  421. {
  422. if(::PathFileExists (localfile)==0)
  423. {
  424. CFile fp;
  425. if(!fp.Open (localfile, CFile::modeCreate|CFile::modeWrite))
  426. {
  427. g_failstr="打开文件失败";
  428. return 0;
  429. }
  430. BYTE a[1024];
  431. fp.Write (a, sizeof(BYTE)*1024);
  432. fp.Close ();
  433. }
  434. }
  435. // 打开本地文件
  436. // if(!datafile.Open(localfile,(get?CFile::modeWrite|CFile::modeCreate:CFile::modeRead)))
  437. if(!datafile.Open(localfile,(CFile::modeRead|CFile::shareDenyNone)))
  438. {
  439. g_failstr="打开文件失败2";
  440. m_retmsg.LoadString(IDS_FTPMSG4);
  441. return FALSE;
  442. }
  443. fileleng=datafile.GetLength ();
  444. //二进制传输模式
  445. if(!FTPcommand("TYPE I"))
  446. {
  447. datafile.Close ();
  448. return FALSE;
  449. }
  450. //被动接收
  451. if(pasv && m_pasved==0)
  452. {
  453. if(!FTPcommand("PASV"))
  454. {
  455. datafile.Close ();
  456. return FALSE;
  457. }
  458. //获取服务器IP
  459. if((i=m_retmsg.Find("("))==-1||(j=m_retmsg.Find(")"))==-1)
  460. {
  461. datafile.Close ();
  462. return FALSE;
  463. }
  464. temp=m_retmsg.Mid(i+1,(j-i)-1);
  465. i=temp.ReverseFind(',');
  466. serversock=atol(temp.Right(temp.GetLength()-(i+1)));
  467. temp=temp.Left(i);
  468. i=temp.ReverseFind(',');
  469. serversock+=256*atol(temp.Right(temp.GetLength()-(i+1))); // add ms byte to server socket
  470. rhost=temp.Left(i);
  471. while(1)
  472. {
  473. //转换,
  474. if((i=rhost.Find(","))==-1)
  475. break;
  476. rhost.SetAt(i,'.');
  477. }
  478. }
  479. //主动传输模式
  480. else if(pasv==0)
  481. {
  482. m_retmsg.LoadString(IDS_FTPMSG6);
  483. //获取本地控制连接IP
  484. if(!m_Ctrlsok->GetSockName(lhost,localsock))
  485. {
  486. datafile.Close ();
  487. return FALSE;
  488. }
  489. while(1)
  490. {
  491. //转换.
  492. if((i=lhost.Find("."))==-1) break;
  493. lhost.SetAt(i,',');
  494. }
  495. //创建侦听Socket
  496. if((!sockSrvr.Create(0,SOCK_STREAM,NULL))||(!sockSrvr.Listen()))
  497. {
  498. datafile.Close ();
  499. return FALSE;
  500. }
  501. if(!sockSrvr.GetSockName(temp,localsock))
  502. {
  503. datafile.Close ();
  504. return FALSE;
  505. }
  506. lhost.Format("%s,%d,%d",lhost,localsock/256,localsock%256);
  507. //发送Port命令
  508. if(!FTPcommand("PORT "+lhost))
  509. {
  510. datafile.Close ();
  511. return FALSE;
  512. }
  513. }
  514. /////////////////////////////////
  515. if(!FTPcommand("CWD \\"))
  516. {
  517. datafile.Close ();
  518. return FALSE;
  519. }
  520. int pos=remotefile.Find ("\\");
  521. while(pos!=-1)
  522. {
  523. CString dir=remotefile.Left (pos);
  524. if(FTPcommand("CWD "+dir)==0)
  525. {
  526. FTPcommand("MKD "+dir);
  527. if(FTPcommand("CWD "+dir)==0)
  528. {
  529. datafile.Close ();
  530. return 0;
  531. }
  532. }
  533. remotefile=remotefile.Right (remotefile.GetLength ()-pos-1);
  534. pos=remotefile.Find ("\\");
  535. }
  536. DWORD oldsended=0;
  537. if(m_check1)
  538. {
  539. FTPcommand("SIZE "+remotefile);
  540. if(m_retmsg.GetLength ()>4)
  541. {
  542. if(m_retmsg.Left (3)=="213")
  543. {
  544. oldsended=atoi(m_retmsg.Right (m_retmsg.GetLength ()-4));
  545. if(oldsended<=fileleng)
  546. {
  547. FTPcommand("REST "+m_retmsg.Right (m_retmsg.GetLength ()-4));
  548. if(m_retmsg.GetLength ()<4)
  549. {
  550. datafile.Close ();
  551. return 0;
  552. }
  553. if(m_retmsg.Left (3)!="350")
  554. {
  555. datafile.Close ();
  556. return 0;
  557. }
  558. }
  559. else
  560. oldsended=0;
  561. }
  562. }
  563. }
  564. ////////////////////////////////
  565. if(!WriteStr("STOR "+remotefile))
  566. {
  567. datafile.Close ();
  568. return FALSE;
  569. }
  570. if(pasv )//&& m_pasved==0)
  571. {
  572. if(!datachannel.Create()) {
  573. m_retmsg.LoadString(IDS_FTPMSG6);
  574. datafile.Close ();
  575. return FALSE;
  576. }
  577. //数据通道连接
  578. datachannel.Connect(rhost,serversock);
  579. m_pasved=1;
  580. }
  581. //获取响应
  582. if(!ReadStr()||m_fc!=1)
  583. {
  584. datafile.Close ();
  585. return FALSE;
  586. }
  587. //通道建立
  588. if(!pasv&&!sockSrvr.Accept(datachannel))
  589. {
  590. datafile.Close ();
  591. return FALSE;
  592. }
  593. if((!datachannel.AsyncSelect(0))||(!datachannel.IOCtl(FIONBIO,&lpArgument)))
  594. {
  595. m_retmsg.LoadString(IDS_FTPMSG6);datafile.Close ();
  596. return FALSE;
  597. }
  598. if(oldsended)
  599. {
  600. datafile.Seek(oldsended,CFile::current);
  601. sended+=oldsended;
  602. }
  603. //开始数据传输
  604. while(1)
  605. {
  606. TRY
  607. {
  608. //获取数据
  609. if(0)
  610. {
  611. //传输完毕
  612. if(!(num=datachannel.Receive(cbuf,BUFSIZE,0))||num==SOCKET_ERROR)
  613. break;
  614. else
  615. datafile.Write(cbuf,num);
  616. }
  617. //上传数据
  618. else
  619. {
  620. if(1)
  621. {
  622. MyLock lock("g_bActiveaccess");
  623. g_bActive[m_pos]=1;
  624. }
  625. if(m_bStop)
  626. {
  627. if(*m_bStop)
  628. {
  629. datachannel.Close();m_pasved=0;
  630. datafile.Close();
  631. return 3;
  632. break;
  633. }
  634. }
  635. if(g_pMainWnd->m_bTerminate1[m_pos])
  636. {
  637. datachannel.Close();m_pasved=0;
  638. datafile.Close();
  639. return 3;
  640. break;
  641. }
  642. //传输完毕
  643. if(!(numread=datafile.Read(cbuf,BUFSIZE)))
  644. break;
  645. if((numsent=datachannel.Send(cbuf,numread,0))==SOCKET_ERROR)
  646. break;
  647. //发送的数据少于实际文件,重新定位文件指针
  648. if(numread!=numsent)
  649. datafile.Seek(numsent-numread,CFile::current);
  650. sended+=numsent;
  651. if(fileleng/100>0)
  652. {
  653. temp.Format("当前文件:%d", sended/(fileleng/100));
  654. g_pMainWnd->ModifyStaus4 (m_path, temp+"%", m_pos);
  655. }
  656. }
  657. }
  658. CATCH (CException,e) {
  659. m_retmsg.LoadString(IDS_FTPMSG5);
  660. {
  661. // WriteLogin("传输异常"+m_retmsg);
  662. datafile.Close ();
  663. return FALSE;
  664. }
  665. }
  666. END_CATCH
  667. }
  668. //数据通道关闭
  669. datachannel.Close();
  670. datafile.Close();
  671. //获取响应
  672. if(!FTPcommand("NOOP"))
  673. return FALSE;
  674. if(blast)::DeleteFile (localfile);
  675. return TRUE;
  676. }
  677. catch(...)
  678. {
  679. // WriteLogin("传输异常!");
  680. return 0;
  681. }
  682. }
  683. // function to send a command string on the server control channel
  684. BOOL CFTPSend::WriteStr(CString outputstring)
  685. {
  686. //载入错误信息,便于后面显示
  687. m_retmsg.LoadString(IDS_FTPMSG6);
  688. //发送信息
  689. TRY {
  690. m_pCtrlTxarch->WriteString(outputstring+"\r\n");
  691. m_pCtrlTxarch->Flush();
  692. }
  693. //捕获异常
  694. CATCH(CException,e) {
  695. return FALSE;
  696. }
  697. END_CATCH
  698. return TRUE;
  699. }
  700. // this function gets the server response line
  701. BOOL CFTPSend::ReadStr()
  702. {
  703. //响应码
  704. int retcode;
  705. //读取信息
  706. if(!ReadStr2())
  707. return FALSE;
  708. //根据获取的信息确定是否成功
  709. if(m_retmsg.GetLength()<4||m_retmsg.GetAt(3)!='-')
  710. return TRUE;
  711. //获取响应码
  712. retcode=atol(m_retmsg);
  713. while(1)
  714. {
  715. //处理多行响应
  716. if(m_retmsg.GetLength()>3&&(m_retmsg.GetAt(3)==' '&&atol(m_retmsg)==retcode))
  717. return TRUE;
  718. if(!ReadStr2())
  719. return FALSE;
  720. }
  721. }
  722. //////////////////////////////////////////////////////////////////////
  723. // Private functions
  724. //////////////////////////////////////////////////////////////////////
  725. // read a single response line from the server control channel
  726. BOOL CFTPSend::ReadStr2()
  727. {
  728. TRY
  729. {
  730. //利用序列化读取信息
  731. if(!m_pCtrlRxarch->ReadString(m_retmsg))
  732. {
  733. //载入失败信息
  734. m_retmsg.LoadString(IDS_FTPMSG6);
  735. return FALSE;
  736. }
  737. }
  738. //捕获异常
  739. CATCH(CException,e)
  740. {
  741. m_retmsg.LoadString(IDS_FTPMSG6);
  742. return FALSE;
  743. }
  744. END_CATCH
  745. //获取响应信息的第一个字节
  746. if(m_retmsg.GetLength()>0)
  747. m_fc=m_retmsg.GetAt(0)-48;
  748. return TRUE;
  749. }
  750. // open the control channel to the FTP server
  751. BOOL CFTPSend::OpenControlChannel(CString serverhost,int serverport)
  752. {
  753. m_retmsg.LoadString(IDS_FTPMSG2);
  754. if(!(m_Ctrlsok=new CSocket))
  755. return FALSE;
  756. if(!(m_Ctrlsok->Create()))
  757. return FALSE;
  758. m_retmsg.LoadString(IDS_FTPMSG3);
  759. //控制通道Socket连接服务器
  760. if(!(m_Ctrlsok->Connect(serverhost,serverport)))
  761. return FALSE;
  762. m_retmsg.LoadString(IDS_FTPMSG2);
  763. //连接成功后创建序列化对象
  764. if(!(m_pCtrlsokfile=new CSocketFile(m_Ctrlsok)))
  765. return FALSE;
  766. if(!(m_pCtrlRxarch=new CArchive(m_pCtrlsokfile,CArchive::load)))
  767. return FALSE;
  768. if(!(m_pCtrlTxarch=new CArchive(m_pCtrlsokfile,CArchive::store)))
  769. return FALSE;
  770. return TRUE;
  771. }
  772. // close the control channel to the FTP server
  773. void CFTPSend::CloseControlChannel()
  774. {
  775. if(m_pCtrlTxarch) delete m_pCtrlTxarch;
  776. m_pCtrlTxarch=NULL;
  777. if(m_pCtrlRxarch) delete m_pCtrlRxarch;
  778. m_pCtrlRxarch=NULL;
  779. if(m_pCtrlsokfile) delete m_pCtrlsokfile;
  780. m_pCtrlsokfile=NULL;
  781. if(m_Ctrlsok) delete m_Ctrlsok;
  782. m_Ctrlsok=NULL;
  783. return;
  784. }
  785. //CAsyncSocket