FtpLib.cpp
上传用户:tjfeida
上传日期:2013-03-10
资源大小:1917k
文件大小:28k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. // Ftp.cpp: implementation of the CFtp class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. /*********************************************
  5. **该文件是属于WolfFTP工程中的。如果有什么问题
  6. **请联系
  7. **         tablejiang@21cn.com
  8. **或者访问
  9. **         http://wolfftp.51.net
  10. **以得到最新的支持。
  11. *********************************************/
  12. #include "stdafx.h"
  13. #include "FtpLib.h"
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[]=__FILE__;
  17. #define new DEBUG_NEW
  18. #endif
  19. //////////////////////////////////////////////////////////////////////
  20. // Construction/Destruction
  21. //////////////////////////////////////////////////////////////////////
  22. CFtpLib::CFtpLib()
  23. {
  24. m_bRun = true ;
  25. }
  26. CFtpLib::~CFtpLib()
  27. {
  28. }
  29. /***********************************************************
  30. ** @Description:
  31. ** connect the ftp server .
  32. ** @Note:
  33. ** LPCTSTR lpszHostName : the host address .
  34. **
  35. ** @Return: the connected socket handle .
  36. ** @Author: Table.JHM.太子
  37. ** @e-mail: tablejiang@21cn.com
  38. ** Date:     2001 3 26
  39. *************************************************************/
  40. SOCKET CFtpLib::ConnectServer( LPCTSTR lpszHostName )
  41. {
  42. LPHOSTENT lpHostent ;
  43. LPSERVENT lpServent ;
  44. SOCKADDR_IN sockAddr ;
  45. WORD nPort ;
  46. int bConnect ;
  47. int iWinsockErr ;
  48. SOCKET hConnectSocket ;
  49. //get host ip address .
  50. if( !(lpHostent = gethostbyname( lpszHostName ) ) )
  51. {
  52. iWinsockErr = WSAGetLastError( ) ;
  53. sprintf( m_szFtpBuffer , " %d error while get server ip addr!" , iWinsockErr ) ;
  54. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  55. return INVALID_SOCKET ;
  56. }
  57. if( ( hConnectSocket = socket( AF_INET , SOCK_STREAM , 0 ) ) == INVALID_SOCKET )
  58. {
  59. iWinsockErr = WSAGetLastError() ;
  60. sprintf( m_szFtpBuffer , " %d error while create connect socket!" , iWinsockErr )  ;
  61. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  62. return INVALID_SOCKET ;
  63. }
  64. //get default ftp host port .
  65. lpServent = getservbyname( "ftp" , 0 ) ;
  66. if( lpServent == NULL )
  67. nPort = htons( DEFAULT_FTP_PORT ) ;
  68. else
  69. nPort = lpServent->s_port ;
  70. //set server address .
  71. sockAddr.sin_family = AF_INET ;
  72. sockAddr.sin_port = nPort ;
  73. sockAddr.sin_addr = *((LPIN_ADDR)*lpHostent->h_addr_list ) ;
  74. bConnect = connect( hConnectSocket , (LPSOCKADDR)&sockAddr , sizeof( SOCKADDR_IN ) ) ;
  75. if( bConnect == SOCKET_ERROR ) 
  76. {
  77. iWinsockErr = WSAGetLastError( ) ;
  78. sprintf( m_szFtpBuffer , "%d error while connect server !" , iWinsockErr ) ;
  79. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  80. return INVALID_SOCKET ;
  81. }
  82. //check the socket is ready to read .
  83. //IsReadyToRead( hConnectSocket ) ;
  84. //get the server reply code .
  85. UINT nRelpyCode = GetServerReply( hConnectSocket ) ;
  86. if( nRelpyCode >= 400 || nRelpyCode <= 0 )
  87. {
  88. //closesocket( hConnectSocket ) ;
  89. return hConnectSocket ;
  90. }
  91. else
  92. {
  93. return hConnectSocket ;
  94. }
  95. }
  96. /***********************************************************
  97. ** @Description:
  98. ** check the socket connect is ready to read ?
  99. **
  100. ** @Note:
  101. ** SOCKET hSocket : socket handle want be check .
  102. **
  103. ** @Return: if ready to read true ,else false .
  104. ** @Author: Table.JHM.太子
  105. ** @e-mail: tablejiang@21cn.com
  106. ** Date: 2001 3 26
  107. *************************************************************/
  108. BOOL CFtpLib::IsReadyToRead(SOCKET hSocket)
  109. {
  110. FD_SET ReadSet ;
  111. TIMEVAL timeout ;
  112. int nReady ;
  113. int iWinsockErr ;
  114. //set time.
  115. //wait one second .
  116. timeout.tv_sec = 1 ;
  117. timeout.tv_usec = 0 ;
  118. FD_ZERO( &ReadSet ) ;
  119. FD_SET( hSocket , &ReadSet ) ;
  120. //select the socket .
  121. nReady = select( 0 , &ReadSet , 0 , 0 , &timeout ) ;
  122. if( nReady == SOCKET_ERROR )
  123. {
  124. iWinsockErr = WSAGetLastError( ) ;
  125. sprintf( m_szFtpBuffer , " %d error while select function read !" , iWinsockErr ) ;
  126. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  127. return FALSE ;
  128. }
  129. //check socket .
  130. if( FD_ISSET( hSocket , &ReadSet ) )
  131. {
  132. return TRUE ;
  133. }
  134. else
  135. return FALSE ;
  136. }
  137. /***********************************************************
  138. ** @Description:
  139. ** receive the reply string from server .
  140. **
  141. ** @Note:
  142. ** SOCKET hSocket : the connected socket handle.
  143. **
  144. ** @Return: the server reply code.
  145. ** @Author: Table.JHM.太子
  146. ** @e-mail: tablejiang@21cn.com
  147. ** Date:  2001 3 26
  148. ***********************************************************/
  149. int CFtpLib::GetServerReply(SOCKET hSocket)
  150. {
  151. char szBuffer[1024] ;
  152. int iLength ;
  153. int iBuffer = 0 ;
  154. BOOL bNeedReceive = true ;
  155. char szMultiLineHead[MAX_PATH] ;
  156. UINT nReplyCode ;
  157. memset( szMultiLineHead , 0 ,MAX_PATH ) ;
  158. while( bNeedReceive )
  159. {
  160. memset( szBuffer , 0 , 1024 ) ;
  161. iBuffer = 0 ;
  162. //because the reply string possibly is multi line .
  163. //so we must peek the reply info before receive it.
  164. //peek the message .
  165. if( ( iLength = recv( hSocket , szBuffer , 1024 , MSG_PEEK ) ) == SOCKET_ERROR )
  166. {
  167. int iWinsockErr = WSAGetLastError( ) ;
  168. sprintf( m_szFtpBuffer , " %d error while recv server reply!" , iWinsockErr ) ;
  169. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  170. return ( ERROR_FTP_CODE ) ;
  171. }
  172. if( iLength <= 0 )
  173. return (ERROR_FTP_CODE );
  174. //debug
  175. //Log the file .
  176. /*
  177. CFile file ;
  178. file.Open( "e:\receive.txt" , CFile::modeWrite ) ;
  179. file.SeekToEnd( ) ;
  180. file.Write( szBuffer , iLength ) ;
  181. file.Close() ;
  182. */
  183. //find the line end .
  184. while( szBuffer[iBuffer] != 'n' )
  185. {
  186. iBuffer ++ ;
  187. if( iBuffer >= iLength )
  188. break ;
  189. }
  190. //skip the 'n'
  191. iBuffer ++ ;
  192. TRACE( "%drn" , iLength ) ;
  193. //receive server reply string .
  194. if( ( iLength = recv( hSocket , szBuffer , iBuffer , 0 ) ) == SOCKET_ERROR )
  195. {
  196. int iWinsockErr = WSAGetLastError( ) ;
  197. sprintf( m_szFtpBuffer , " %d error while recv server reply!" , iWinsockErr ) ;
  198. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  199. return ( ERROR_FTP_CODE ) ;
  200. }
  201. if( iLength < 1024 )
  202. szBuffer[iLength] = 0 ;
  203. else
  204. szBuffer[1023] = 0 ;
  205. //notify the parent wnd.
  206. SendMsgToParentWnd( szBuffer , false ) ;
  207. if( strlen( szMultiLineHead ) == 0 )
  208. {
  209. nReplyCode = GetReplyCode( szBuffer ) ;
  210. itoa( (int)nReplyCode , szMultiLineHead , 10 ) ;
  211. if( szBuffer[3] == '-' )
  212. bNeedReceive = true ;
  213. else
  214. bNeedReceive = false ;
  215. }
  216. else
  217. {
  218. if( strncmp( szMultiLineHead , szBuffer , 3 ) == 0 )
  219. {
  220. if( szBuffer[3] == '-' )
  221. bNeedReceive = true ;
  222. else
  223. bNeedReceive = false ;
  224. }
  225. else
  226. bNeedReceive = true ;
  227. }
  228. }
  229. nReplyCode = GetReplyCode ( szBuffer ) ;
  230. return nReplyCode ;
  231. }
  232. /***********************************************************
  233. ** @Description:
  234. ** Get server reply command code.
  235. **
  236. ** @Note:
  237. ** LPSTR lpszBuffer : the reply string .
  238. **
  239. ** @Return: server reply code.
  240. ** @Author: Table.JHM.太子
  241. ** @e-mail: tablejiang@21cn.com
  242. ** Date: 2001 3 26
  243. *************************************************************/
  244. UINT CFtpLib::GetReplyCode(LPSTR lpszBuffer)
  245. {
  246. //get the server reply code , 
  247. //the ftp server will return a string after receive command , 
  248. //first three char in this string is the server reply code .
  249. UINT nCode ;
  250. char cBak ;
  251. cBak = *(lpszBuffer + 3 );
  252. *( lpszBuffer + 3 ) = 0 ;
  253. nCode = atoi( lpszBuffer ) ;
  254. *(lpszBuffer + 3 ) = cBak ;
  255. return nCode ;
  256. }
  257. /***********************************************************
  258. ** @Description:
  259. ** send a command to ftp server ,and receive the reply
  260. **
  261. ** @Note:
  262. ** LPSTR szCommandBuffer : the command string 
  263. ** SOCKET hSocket : the connected socket handle.
  264. **
  265. ** @Return: 
  266. ** @Author: Table.JHM.太子
  267. ** @e-mail: tablejiang@21cn.com
  268. ** Date: 2001 3 26
  269. *************************************************************/
  270. UINT CFtpLib::SendFtpCommand(LPSTR szCommandBuffer , SOCKET hSocket )
  271. {
  272. if( !m_bRun )
  273. return ERROR_FTP_CODE ;
  274. //send command . and after send will check server reply .
  275. if( send( hSocket , szCommandBuffer , strlen( szCommandBuffer ) , 0 ) == SOCKET_ERROR ) 
  276. {
  277. int iWinsockErr = WSAGetLastError( ) ;
  278. sprintf( m_szFtpBuffer , " %d error while Send ftp command !" , iWinsockErr ) ;
  279. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  280. return ( ERROR_FTP_CODE ) ;
  281. }
  282. //Send msg to window .
  283. SendMsgToParentWnd( szCommandBuffer , true ) ;
  284. return GetServerReply( hSocket ) ;
  285. }
  286. /***********************************************************
  287. ** @Description:
  288. ** close the ftp control connect socket handle .
  289. *
  290. ** @Note:
  291. ** SOCKET hSocket : the connected socket handle .
  292. **
  293. ** @Return: true .
  294. ** @Author: Table.JHM.太子
  295. ** @e-mail: tablejiang@21cn.com
  296. ** Date: 2001 3 26
  297. *************************************************************/
  298. BOOL CFtpLib::CloseFtpConnect( SOCKET hSocket )
  299. {
  300. closesocket( hSocket ) ;
  301. return TRUE ;
  302. }
  303. /***********************************************************
  304. ** @Description:
  305. ** Create the data link .
  306. **
  307. ** @Note:
  308. ** SOCKET hControlSocket : the control connected socket handle .
  309. ** @Return: if success return the data listen socket handle , 
  310. ** else return INVALID_SOCKET .
  311. **
  312. ** @Author: Table.JHM.太子
  313. ** @e-mail: tablejiang@21cn.com
  314. ** Date: 2001 3 26
  315. *************************************************************/
  316. //this function is used to create date link .
  317. SOCKET CFtpLib::CreateListenCannel(SOCKET hControlSocket)
  318. {
  319. SOCKADDR_IN sockaddr ;
  320. SOCKET hListenSocket ;
  321. if( ( hListenSocket = socket( AF_INET , SOCK_STREAM , 0 ) ) == INVALID_SOCKET )
  322. {
  323. int iWinsockErr = WSAGetLastError( ) ;
  324. sprintf( m_szFtpBuffer , "%d error when create listen socket !" , iWinsockErr ) ;
  325. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  326. return ( INVALID_SOCKET ) ;
  327. }
  328. //make address.
  329. sockaddr.sin_family = AF_INET ;
  330. sockaddr.sin_port = htons( 0 ) ;
  331. sockaddr.sin_addr.s_addr = INADDR_ANY ;
  332. if( bind( hListenSocket , (LPSOCKADDR)&sockaddr , sizeof( sockaddr ) ) )
  333. {
  334. int iWinsockErr = WSAGetLastError( ) ;
  335. sprintf( m_szFtpBuffer , "%d error when bind the listen socket !" , iWinsockErr ) ;
  336. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  337. return ( INVALID_SOCKET ) ;
  338. }
  339. if( listen( hListenSocket , 1 ) )
  340. {
  341. int iWinsockErr = WSAGetLastError( ) ;
  342. sprintf( m_szFtpBuffer , "%d error when listening " , iWinsockErr ) ;
  343. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  344. return ( INVALID_SOCKET ) ;
  345. }
  346. return PrepareDataCannel( hListenSocket , hControlSocket )  ;
  347. }
  348. /***********************************************************
  349. ** @Description:
  350. ** prepare the data cannel , transmit the data.
  351. **
  352. ** @Note:
  353. ** SOCKET hListenSocket : Listen data socket hanle .
  354. ** SOCKET hControlSocket : Control socket handle .
  355. **
  356. ** @Return: the data link connect socket .
  357. ** @Author: Table.JHM.太子
  358. ** @e-mail: tablejiang@21cn.com
  359. ** Date:  2001 3 26
  360. *************************************************************/
  361. SOCKET CFtpLib::PrepareDataCannel(SOCKET hListenSocket, SOCKET hControlSocket)
  362. {
  363. SOCKADDR_IN sockaddr ;
  364. int iLength ;
  365. UINT nPort ;
  366. UINT nReplyCode ;
  367. iLength = sizeof( sockaddr ) ;
  368. // Get the address for the hListenSocket
  369. if( getsockname( hListenSocket , (LPSOCKADDR)&sockaddr , &iLength ) == SOCKET_ERROR )
  370. {
  371. int iWinsockErr = WSAGetLastError( ) ;
  372. sprintf( m_szFtpBuffer , "%d error when get listen socket name!" , iWinsockErr ) ;
  373. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  374. return ( INVALID_SOCKET ) ;
  375. }
  376. nPort = sockaddr.sin_port ;
  377. iLength = sizeof( sockaddr ) ;
  378. if( getsockname( hControlSocket , ( LPSOCKADDR )&sockaddr , &iLength ) == SOCKET_ERROR )
  379. {
  380. int iWinsockErr = WSAGetLastError( ) ;
  381. sprintf( m_szFtpBuffer , "%d error when get control socket name!" , iWinsockErr ) ;
  382. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  383. return ( INVALID_SOCKET ) ;
  384. }
  385. //use PORT command to tell server connect this socket , 
  386. //after server receive this command , server will create a socket to connect 
  387. //this port .
  388. char szCommand[MAX_PATH];
  389. sprintf( szCommand , "PORT %d,%d,%d,%d,%d,%drn" , 
  390. sockaddr.sin_addr.S_un.S_un_b.s_b1,
  391. sockaddr.sin_addr.S_un.S_un_b.s_b2,
  392. sockaddr.sin_addr.S_un.S_un_b.s_b3,
  393. sockaddr.sin_addr.S_un.S_un_b.s_b4,
  394. nPort&0xFF , 
  395. nPort >> 8 );
  396. //send command .
  397. if( ( nReplyCode = SendFtpCommand( szCommand , hControlSocket ) ) != 200 )
  398. {
  399. int iWinsockErr = WSAGetLastError( ) ;
  400. sprintf( m_szFtpBuffer , "%d error when Send ftp command !" , iWinsockErr ) ;
  401. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  402. return ( INVALID_SOCKET ) ;
  403. }
  404. else
  405. return ( hListenSocket ) ;
  406. }
  407. /***********************************************************
  408. ** @Description:
  409. ** Accept data connect socket .
  410. **
  411. ** @Note:
  412. ** SOCKET hListenSocket : the data listen socket handle .
  413. **
  414. ** @Return: 
  415. ** @Author: Table.JHM.太子
  416. ** @e-mail: tablejiang@21cn.com
  417. ** Date: 2001 3 26
  418. *************************************************************/
  419. SOCKET CFtpLib::AcceptDataConnect(SOCKET hListenSocket)
  420. {
  421. SOCKET hDataConnect = 0 ;
  422. SOCKADDR_IN sockaddr ;
  423. int iLength ;
  424. iLength = sizeof( sockaddr ) ;
  425. //accept the data socket .
  426. hDataConnect = accept( hListenSocket , (LPSOCKADDR)&sockaddr , &iLength ) ;
  427. if( hDataConnect == INVALID_SOCKET )
  428. {
  429. int iWinsockErr = WSAGetLastError( ) ;
  430. sprintf( m_szFtpBuffer , "%d error when accept data connect !" , iWinsockErr ) ;
  431. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  432. return ( INVALID_SOCKET ) ;
  433. }
  434. return ( hDataConnect ) ;
  435. }
  436. /***********************************************************
  437. ** @Description:
  438. **
  439. ** @Note:
  440. **
  441. ** @Return: 
  442. ** @Author: Table.JHM.太子
  443. ** @e-mail: tablejiang@21cn.com
  444. ** Date: 2001 3 26
  445. *************************************************************/
  446. UINT CFtpLib::ReadDataCannel(SOCKET hControlSocket, SOCKET hDataSocket, char *Buffer)
  447. {
  448. return 1;
  449. }
  450. /***********************************************************
  451. ** @Description:
  452. ** read the data from data connect and , wirte it to 
  453. ** local file .
  454. **
  455. ** @Note:
  456. ** SOCKET hControlSocket : the control socket handle .
  457. ** SOCKET hDataSocket : the data connect socket handle .
  458. ** HANDLE hFile : the write file handle.
  459. ** __int64 iFileSize : file transmit file size .
  460. **
  461. ** @Return: after transmit complete , the server return code 
  462. ** @Author: Table.JHM.太子
  463. ** @e-mail: tablejiang@21cn.com
  464. ** Date: 2001 3 26
  465. *************************************************************/
  466. UINT CFtpLib::ReadDataCannelToFile( SOCKET hControlSocket, SOCKET hDataSocket, HANDLE hFile , __int64 iFileSize )
  467. {
  468. DWORD nByteRec = 0 ;
  469. __int64 lDataNum = 0 ;
  470. char ReceiveBuffer[2048] ;
  471. m_hDataSocket = hDataSocket ;
  472. int iProgress = 0 ;
  473. int iSpeed = 0 ;
  474. //get start time .
  475. DWORD dwStart = GetTickCount( ) ;
  476. DWORD dwEnd = dwStart ;
  477. //receive data from net , and write it to local file .
  478. do
  479. {
  480. //receive data.
  481. nByteRec = recv( hDataSocket , ReceiveBuffer , 2048 , 0 ) ;
  482. if( nByteRec == SOCKET_ERROR )
  483. break ;
  484. if( nByteRec > 0 )
  485. {
  486. //total receive bytes.
  487. lDataNum += nByteRec ;
  488. if( !WriteFile( hFile , ReceiveBuffer , nByteRec , &nByteRec , NULL ) )
  489. {
  490. break ;
  491. }
  492. //make progress percent.
  493. if( iFileSize != 0 )
  494. iProgress = ( int )( lDataNum * 100 / iFileSize ) ;
  495. else
  496. iProgress = 100 ;
  497. //get end time .
  498. dwEnd = GetTickCount() ;
  499. //get transmit speed .
  500. iSpeed = GetTransmitSpeed( dwStart , dwEnd , lDataNum ) ;
  501. ::PostMessage( m_hParentWnd , FTP_TRANSMIT_DATA_MSG , iProgress , iSpeed ) ;
  502. }
  503. }
  504. while( nByteRec > 0  );
  505. //close data socket handle .
  506. closesocket( hDataSocket ) ;
  507. m_hDataSocket = NULL ;
  508. if( nByteRec == SOCKET_ERROR )
  509. return false ;
  510. return ( GetServerReply( hControlSocket ) ) ;
  511. }
  512. /***********************************************************
  513. ** @Description:
  514. ** global function , use for initialize socket lib .
  515. **
  516. ** @Note:
  517. ** void
  518. **
  519. ** @Return: success return true ,else false.
  520. ** @Author: Table.JHM.太子
  521. ** @e-mail: tablejiang@21cn.com
  522. ** Date: 2001 3 26
  523. *************************************************************/
  524. BOOL InitSocket( )
  525. {
  526. WSADATA wsadata ;
  527. if( WSAStartup( MAKEWORD( 1 , 1 ) , &wsadata ) )
  528. {
  529. return false ;
  530. }
  531. else
  532. {
  533. return true ;
  534. }
  535. }
  536. /***********************************************************
  537. ** @Description:
  538. ** global function , uninit the socket lib.
  539. **
  540. ** @Note:
  541. ** void .
  542. **
  543. ** @Return: success return true ,else return false .
  544. ** @Author: Table.JHM.太子
  545. ** @e-mail: tablejiang@21cn.com
  546. ** Date: 2001 3 26
  547. *************************************************************/
  548. BOOL UnInitSocket( )
  549. {
  550. if( WSACleanup( ) )
  551. {
  552. return false ;
  553. }
  554. else
  555. return true ;
  556. }
  557. /***********************************************************
  558. ** @Description:
  559. ** upload a file to server .
  560. **
  561. ** @Note:
  562. ** SOCKET hControlSocket : connected control socket .
  563. ** SOCKET hDataSocket : connected data socket .
  564. ** HANDLE hFile : the open file handle .
  565. **
  566. ** @Return: 
  567. ** @Author: Table.JHM.太子
  568. ** @e-mail: tablejiang@21cn.com
  569. ** Date: 2001 3 26
  570. *************************************************************/
  571. UINT CFtpLib::WriteDataCannelFromFile(SOCKET hControlSocket, SOCKET hDataSocket, HANDLE hFile )
  572. {
  573. DWORD nByteRec = 0 ;
  574. DWORD nByteSend = 0 ;
  575. char SendBuffer[RECEIVE_SIZE] ;
  576. //backup data socket handle .
  577. m_hDataSocket = hDataSocket ;
  578. __int64 nFileSize = 0 ;
  579. __int64 nSendSize = 0 ;
  580. DWORD dwFileSizeHigh = 0 ;
  581. DWORD dwFileSizeLow = 0 ;
  582. int iPrecent = 0 ;
  583. int iSpeed = 0 ;
  584. //get start time
  585. DWORD dwStart = GetTickCount( ) ;
  586. DWORD dwEnd = dwStart;
  587. //get file size .
  588. dwFileSizeLow = GetFileSize( hFile , &dwFileSizeHigh ) ;
  589. nFileSize = dwFileSizeHigh ;
  590. nFileSize = dwFileSizeLow + (nFileSize << 32 ) ;
  591. //transmit data.
  592. do
  593. {
  594. //read data from file.
  595. if( ReadFile( hFile , SendBuffer , RECEIVE_SIZE , &nByteRec , NULL ) )
  596. {
  597. if( nByteRec > 0 )
  598. {
  599. //send data.
  600. nByteSend = send( hDataSocket , SendBuffer , nByteRec , 0 ) ;
  601. if( nByteSend <= 0 || nByteSend == SOCKET_ERROR )
  602. {
  603. break ;
  604. }
  605. //total transmit bytes
  606. nSendSize += nByteRec ;
  607. //get end time .
  608. dwEnd = GetTickCount() ;
  609. //get transmit precent.
  610. iPrecent = (int) ( nSendSize * 100 / nFileSize );
  611. //get transmit speed .
  612. iSpeed = GetTransmitSpeed( dwStart , dwEnd , nSendSize ) ;
  613. ::PostMessage( m_hParentWnd , FTP_TRANSMIT_DATA_MSG , iPrecent , iSpeed ) ;
  614. //dwStart = GetTickCount( ) ;
  615. }
  616. else
  617. break ;
  618. }
  619. }
  620. while( nByteRec > 0 );
  621. //close handle .
  622. closesocket( hDataSocket ) ;
  623. m_hDataSocket = NULL ;
  624. if( nByteSend == SOCKET_ERROR )
  625. return false ;
  626. return ( GetServerReply( hControlSocket ) ) ;
  627. }
  628. /***********************************************************
  629. ** @Description:
  630. ** this function is parse the server file list info.
  631. ** before you can understand this function ,you must 
  632. ** know the ftp server reply file list format.
  633. **
  634. ** @Note:
  635. ** int * pos[in/out] : the pointer position of file list string.
  636. ** char* word[out] : the buffer use for store current word.
  637. ** int iwordsize[in] : the buffer size .
  638. ** CString* string[in] : the file list string .
  639. **
  640. ** @Return: 
  641. ** @Author: Table.JHM.太子
  642. ** @e-mail: tablejiang@21cn.com
  643. ** Date: 2001 3 26
  644. *************************************************************/
  645. UINT CFtpLib::GetSubItem(int *pos, char *word , int iwordsize , CString* string )
  646. {
  647. int iPos = *pos ;
  648. int iLength = string->GetLength() ;
  649. //zero memory 
  650. memset( word , 0 , iwordsize ) ;
  651. //if pos overtop the string length .
  652. if( iPos >= ( iLength - 1 ) )
  653. return 2 ;
  654. //skip the space char .
  655. while( string->GetAt( iPos ) == ' ' )
  656. {
  657. iPos ++ ;
  658. if( iPos >= ( iLength - 1 ) || string->GetAt( iPos ) == 'r' )
  659. return 0 ;
  660. }
  661. int iWord = 0 ;
  662. //get word string .
  663. while( !( string->GetAt( iPos ) == ' ' || string->GetAt( iPos ) == 'r' &&
  664. string->GetAt( iPos + 1 ) == 'n' ) )
  665. {
  666. word[iWord++] = string->GetAt( iPos++ ) ;
  667. if( iPos >= iLength - 1 )
  668. return 2 ;
  669. }
  670. //if a word complete.
  671. if( string->GetAt( iPos ) == ' ' )
  672. {
  673. *pos = iPos ;
  674. return 1 ;
  675. }
  676. //if a line complete .
  677. if( string->GetAt( iPos ) == 'r' )
  678. {
  679. iPos += 2 ;
  680. *pos = iPos ;
  681. return 2 ;
  682. }
  683. return 0 ;
  684. }
  685. /***********************************************************
  686. ** @Description:
  687. ** send message string to parent window .
  688. **
  689. ** @Note:
  690. ** LPSTR szMsg : the message string .
  691. ** BOOL bCommand : is command or server reply .
  692. **
  693. ** @Return: true .
  694. ** @Author: Table.JHM.太子
  695. ** @e-mail: tablejiang@21cn.com
  696. ** Date: 2001 3 26
  697. *************************************************************/
  698. BOOL CFtpLib::SendMsgToParentWnd(LPSTR szMsg, BOOL bCommand)
  699. {
  700. int iLength = 0 ;
  701. if( bCommand )
  702. {
  703. char* szCommandString ;
  704. memset( m_szFtpBuffer , 0 , sizeof( m_szFtpBuffer ) ) ;
  705. if( strncmp( szMsg , "PASS " , 5 ) == 0 )
  706. {
  707. szMsg[5] = '*' ;
  708. szMsg[6] = '' ;
  709. strcat( szMsg , "rn" ) ;
  710. }
  711. sprintf( m_szFtpBuffer , "COMMAND >   %s" , szMsg ) ;
  712. int iLength = strlen( m_szFtpBuffer ) ;
  713. //new the buffer , this buffer will delete in parent message response function.
  714. szCommandString = new char[iLength + 1] ;
  715. strcpy( szCommandString , m_szFtpBuffer ) ;
  716. szCommandString[iLength] = 0 ;
  717. ::PostMessage( m_hWndInfo.hInfoWnd , FTP_SEND_COMMAND_MSG , 0 , (LPARAM)szCommandString ) ;
  718. }
  719. else
  720. {
  721. char* szReplyString ;
  722. memset( m_szFtpBuffer , 0 , sizeof( m_szFtpBuffer ) ) ;
  723. sprintf( m_szFtpBuffer , "                        %s" , szMsg ) ;
  724. iLength = strlen( m_szFtpBuffer ) ;
  725. //new the buffer , this buffer will delete in parent message response function.
  726. szReplyString = new char[iLength + 1] ;
  727. strcpy( szReplyString , m_szFtpBuffer ) ;
  728. szReplyString[iLength] = 0 ;
  729. ::PostMessage( m_hWndInfo.hInfoWnd , FTP_SERVER_REPLY_MSG , 0 , (LPARAM)szReplyString ) ;
  730. }
  731. return true ;
  732. }
  733. /***********************************************************
  734. ** @Description:
  735. ** user login ftp server.
  736. **
  737. ** @Note:
  738. ** SOCKET hSocket : the connect control socket handle .
  739. ** LPSTR szName : user name .
  740. ** LPSTR szPass : pass word .
  741. **
  742. ** @Return: login success return true ,else return false .
  743. ** @Author: Table.JHM.太子
  744. ** @e-mail: tablejiang@21cn.com
  745. ** Date: 2001 3 26
  746. *************************************************************/
  747. BOOL CFtpLib::UserLogin(SOCKET hSocket, LPSTR szName, LPSTR szPass)
  748. {
  749. char szCommand[MAX_PATH] ;
  750. UINT nReplyCode = 0 ;
  751. //send user name .
  752. sprintf( szCommand , "USER %srn" , szName ) ;
  753. nReplyCode = SendFtpCommand( szCommand , hSocket ) ;
  754. if( nReplyCode >= 400 )
  755. return false ;
  756. //send password 
  757. sprintf( szCommand , "PASS %srn" , szPass ) ;
  758. nReplyCode = SendFtpCommand( szCommand , hSocket ) ;
  759. if( nReplyCode >= 400 )
  760. return false ;
  761. return true ;
  762. }
  763. /***********************************************************
  764. ** @Description:
  765. ** anonymous login function .this function will use 
  766. ** anonymous as user name to login ftp server.
  767. **
  768. ** @Note:
  769. ** SOCKET hSocket : the connect control socket handle .
  770. **
  771. ** @Return: 
  772. ** @Author: Table.JHM.太子
  773. ** @e-mail: tablejiang@21cn.com
  774. ** Date: 2001 3 26
  775. *************************************************************/
  776. BOOL CFtpLib::AnonymousLogin(SOCKET hSocket)
  777. {
  778. //login
  779. char szCommand[MAX_PATH] ;
  780. UINT nReplyCode = 0 ;
  781. sprintf( szCommand , "USER %srn" , "anonymous" ) ;
  782. nReplyCode = SendFtpCommand( szCommand , hSocket ) ;
  783. if( nReplyCode >= 400 )
  784. return false ;
  785. sprintf( szCommand , "PASS %srn" , "anonymous@table.com" ) ;
  786. nReplyCode = SendFtpCommand( szCommand , hSocket ) ;
  787. if( nReplyCode >= 400 )
  788. return false ;
  789. return true ;
  790. }
  791. /***********************************************************
  792. ** @Description:
  793. **
  794. ** @Note:
  795. **
  796. ** @Return: 
  797. ** @Author: Table.JHM.太子
  798. ** @e-mail: tablejiang@21cn.com
  799. ** Date: 2001 3 26
  800. *************************************************************/
  801. /*
  802. BOOL CFtpLib::SetTransmitFilePos(FTPFILEINFO *pFile , HANDLE hFile , SOCKET hSocket )
  803. {
  804. char szBuffer[MAX_PATH] ;
  805. sprintf( szBuffer , "SIZE %srn" , pFile->remotefilename ) ;
  806. //send command . and after send will check server reply .
  807. if( send( hSocket , szBuffer , strlen( szBuffer ) , 0 ) == SOCKET_ERROR ) 
  808. {
  809. int iWinsockErr = WSAGetLastError( ) ;
  810. sprintf( m_szFtpBuffer , " %d error while Send ftp command !" , iWinsockErr ) ;
  811. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  812. return ( ERROR_FTP_CODE ) ;
  813. }
  814. int iLength ;
  815. //peek the message .
  816. if( ( iLength = recv( hSocket , szBuffer , 1024 , MSG_PEEK ) ) == SOCKET_ERROR )
  817. {
  818. int iWinsockErr = WSAGetLastError( ) ;
  819. sprintf( m_szFtpBuffer , " %d error while recv server reply!" , iWinsockErr ) ;
  820. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  821. return ( ERROR_FTP_CODE ) ;
  822. }
  823. if( iLength <= 0 )
  824. return (ERROR_FTP_CODE );
  825. int iBuffer = 0 ;
  826. while( szBuffer[iBuffer] != 'n' )
  827. {
  828. iBuffer ++ ;
  829. if( iBuffer >= iLength )
  830. break ;
  831. }
  832. iBuffer ++ ;
  833. //receive server reply string .
  834. if( ( iLength = recv( hSocket , szBuffer , iBuffer , 0 ) ) == SOCKET_ERROR )
  835. {
  836. int iWinsockErr = WSAGetLastError( ) ;
  837. sprintf( m_szFtpBuffer , " %d error while recv server reply!" , iWinsockErr ) ;
  838. //TRACE( NULL , m_szFtpBuffer , MSGBOX_TITLE , MB_OK ) ;
  839. return ( ERROR_FTP_CODE ) ;
  840. }
  841. if( iLength < 1024 )
  842. szBuffer[iLength] = 0 ;
  843. else
  844. szBuffer[1023] = 0 ;
  845. UINT nReplyCode = GetReplyCode ( szBuffer ) ;
  846. if( nReplyCode >= 400 )
  847. return false ;
  848. char szFileSize[MAX_PATH] ;
  849. __int64 iRemoteFileSize ;
  850. __int64 iLocalFileSize ;
  851. DWORD lSize ;
  852. DWORD hSize ;
  853. strcpy( szFileSize , szBuffer + 4 ) ;
  854. iLength = strlen( szFileSize ) ;
  855. szFileSize[iLength - 2 ] = '' ;
  856. iRemoteFileSize = _atoi64( szFileSize ) ;
  857. lSize = GetFileSize( hFile , &hSize ) ;
  858. iLocalFileSize = hSize ;
  859. iLocalFileSize = iLocalFileSize << 32 ;
  860. iLocalFileSize = lSize ;
  861. if( pFile->bfileput )
  862. {
  863. if( iRemoteFileSize > iLocalFileSize )
  864. {
  865. SendFtpCommand( "RSET 0rn" , hSocket ) ;
  866. return true ;
  867. }
  868. else
  869. {
  870. return true ;
  871. }
  872. }
  873. else
  874. {
  875. if( iRemoteFileSize < iLocalFileSize )
  876. {
  877. SendFtpCommand( "RSET 0rn" , hSocket ) ;
  878. return true ;
  879. }
  880. else
  881. {
  882. return true ;
  883. }
  884. }
  885. return true ;
  886. }
  887. */
  888. /***********************************************************
  889. ** @Description:
  890. ** this function is use for seek file pointer .
  891. **
  892. ** @Note:
  893. ** HANDLE hFile : the open file handle .
  894. ** __int64 distance : the move distance.
  895. ** DWORD MoveMethod : move method , head ,end ??
  896. **
  897. ** @Return: the file pointer moved distance 
  898. ** @Author: Table.JHM.太子
  899. ** @e-mail: tablejiang@21cn.com
  900. ** Date: 2001 3 26
  901. *************************************************************/
  902. __int64 CFtpLib::MyFileSeek(HANDLE hf, __int64 distance, DWORD MoveMethod)
  903. {
  904. LARGE_INTEGER li;
  905. li.QuadPart = distance;
  906. SetLastError( NO_ERROR ) ;
  907. //set file pointer.
  908. li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart, MoveMethod);
  909. if (li.LowPart >= 0 && GetLastError() != NO_ERROR)
  910. {
  911. li.QuadPart = -1;
  912. }
  913. return li.QuadPart;
  914. }
  915. /****************************************************
  916. ** @Description
  917. ** this function is get transmit speed .
  918. **
  919. ** @Parameter
  920. ** DWORD dwStart : the start time.
  921. ** DWORD dwEnd : the end time .
  922. ** __int64 recData : receive data bytes.
  923. **
  924. ** @Return:
  925. ** @Author: Table.JHM.太子
  926. ** @e-mail: tablejiang@21cn.com
  927. ** @Date: 2001 3 26
  928. ****************************************************/
  929. int CFtpLib::GetTransmitSpeed( DWORD dwStart , DWORD dwEnd ,  __int64 recData)
  930. {
  931. if( dwStart >= dwEnd )
  932. return 0 ;
  933. int iSpeed = 0 ;
  934. iSpeed = (int) ( recData * 1000 / ( dwEnd - dwStart ) ) ;
  935. return iSpeed ;
  936. }
  937. /****************************************************
  938. ** @Description
  939. ** stop the command.don't let run.
  940. **
  941. ** @Parameter
  942. ** BOOL bRun : 
  943. **
  944. ** @Return:
  945. ** @Author: Table.JHM.太子
  946. ** e-mail: tablejiang@21cn.com
  947. ** @Date: 2001 3 26
  948. ****************************************************/
  949. void CFtpLib::SetStopSign(BOOL bRun)
  950. {
  951. m_bRun = bRun ;
  952. }