vc上传文件ftp服务器代码,VC FTP服务器程序分析(四)(示例代码)

下面是数据传输的重点-CDataSocket类,函数不多,都比较重要。

1、OnAccept  数据tcp服务器被连接的虚函数,由框架调用。

1 void CDataSocket::OnAccept(intnErrorCode)2 {3 //Accept the connection using a temp CSocket object.

4 CAsyncSocket tmpSocket;5 Accept(tmpSocket);6

7 SOCKET socket =tmpSocket.Detach();8 Close();9

10 Attach(socket);11

12 m_bConnected =TRUE;13

14 CAsyncSocket::OnAccept(nErrorCode);15 }

第7行 得到套接字描述符socket。第8行关闭监听的这个套接字,第11行关联socket与本对象,第12行,标记连接标志。这种处理方法少写一个类。因为tcp监听得一个socket,而连接上来的客户端也需要一个socket来与之通信。这样做适合只有一个客户端的情况。

2、OnReceive  数据接收处理函数

1 intCDataSocket::Receive()2 {3 TRACE("OnReceive\n");4 int nRead = 0;5

6 if (m_pControlSocket->m_nStatus ==STATUS_UPLOAD)7 {8 if (m_File.m_hFile ==NULL)9 return 0;10

11 bytedata[PACKET_SIZE];12 nRead =CAsyncSocket::Receive(data, PACKET_SIZE);13

14 switch(nRead)15 {16 case 0:17 {18 m_File.Close();19 m_File.m_hFile =NULL;20 Close();21 //tell the client the transfer is complete.

22 m_pControlSocket->SendResponse("226 Transfer complete");23 //destroy this socket

24 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);25 break;26 }27 caseSOCKET_ERROR:28 {29 if (GetLastError() !=WSAEWOULDBLOCK)30 {31 m_File.Close();32 m_File.m_hFile =NULL;33 Close();34 m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");35 //destroy this socket

36 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);37 }38 break;39 }40 default:41 {42 TRY43 {44 m_File.Write(data, nRead);45 }46 CATCH_ALL(e)47 {48 m_File.Close();49 m_File.m_hFile =NULL;50 Close();51 m_pControlSocket->SendResponse("450 Can‘t access file.");52 //destroy this socket

53 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);54 return 0;55 }56 END_CATCH_ALL;57 break;58 }59 }60 }61 returnnRead;62 }

如果处于上传状态,那么将接收到的数据写入文件。

3、PreSendFile 与发送文件有关的函数

1 BOOL CDataSocket::PrepareSendFile(LPCTSTR lpszFilename)2 {3 //close file if it‘s already open

4 if (m_File.m_hFile !=NULL)5 {6 m_File.Close();7 }8

9 //open source file

10 if (!m_File.Open(lpszFilename, CFile::modeRead |CFile::typeBinary))11 {12 returnFALSE;13 }14 m_nTotalBytesSend =m_File.GetLength();15

16 if (m_pControlSocket->m_dwRestartOffset m_dwRestartOffset;19 }20 else

21 {22 m_nTotalBytesTransfered = 0;23 }24 returnTRUE;25 }

初始化文件描述符m_File,m_nTotalBytesSend,m_nTotalBytesTransfered。

4、 SendFile函数  调用PrepareSendFile,调用OnSend发送文件。

1 voidCDataSocket::SendFile(LPCTSTR lpszFilename)2 {3 if (!PrepareSendFile(lpszFilename))4 {5 //change status

6 m_pControlSocket->m_nStatus =STATUS_IDLE;7

8 m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");9

10 //destroy this socket

11 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);12 return;13 }14 OnSend(0);15 }

5、SendData 发送数据 是为了LIST命令而准备,发送文件目录列表。

6、OnSend 主要区分了list命令的情况和download的情况。

1 void CDataSocket::OnSend(intnErrorCode)2 {3 CAsyncSocket::OnSend(nErrorCode);4 switch(m_pControlSocket->m_nStatus)5 {6 caseSTATUS_LIST:7 {8 while (m_nTotalBytesTransfered

13 CString strDataBlock;14

15 dwRead =m_strData.GetLength();16

17 if (dwRead <=PACKET_SIZE)18 {19 strDataBlock =m_strData;20 }21 else

22 {23 strDataBlock =m_strData.Left(PACKET_SIZE);24 dwRead =strDataBlock.GetLength();25 }26

27 if ((dwBytes = Send(strDataBlock, dwRead)) ==SOCKET_ERROR)28 {29 if (GetLastError() ==WSAEWOULDBLOCK)30 {31 Sleep(0);32 return;33 }34 else

35 {36 TCHAR szError[256];37 wsprintf(szError, "Server Socket failed to send: %d", GetLastError());38

39 //close the data connection.

40 Close();41

42 m_nTotalBytesSend = 0;43 m_nTotalBytesTransfered = 0;44

45 //change status

46 m_pControlSocket->m_nStatus =STATUS_IDLE;47

48 m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");49

50 //destroy this socket

51 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);52 }53 }54 else

55 {56 m_nTotalBytesTransfered +=dwBytes;57 m_strData =m_strData.Mid(dwBytes);58 }59 }60 if (m_nTotalBytesTransfered ==m_nTotalBytesSend)61 {62 //close the data connection.

63 Close();64

65 m_nTotalBytesSend = 0;66 m_nTotalBytesTransfered = 0;67

68 //change status

69 m_pControlSocket->m_nStatus =STATUS_IDLE;70

71 //tell the client the transfer is complete.

72 m_pControlSocket->SendResponse("226 Transfer complete");73 //destroy this socket

74 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);75 }76 break;77 }78 caseSTATUS_DOWNLOAD:79 {80 while (m_nTotalBytesTransfered

83 bytedata[PACKET_SIZE];84

85 m_File.Seek(m_nTotalBytesTransfered, CFile::begin);86

87 DWORD dwRead =m_File.Read(data, PACKET_SIZE);88

89 intdwBytes;90

91 if ((dwBytes = Send(data, dwRead)) ==SOCKET_ERROR)92 {93 if (GetLastError() ==WSAEWOULDBLOCK)94 {95 Sleep(0);96 break;97 }98 else

99 {100 TCHAR szError[256];101 wsprintf(szError, "Server Socket failed to send: %d", GetLastError());102

103 //close file.

104 m_File.Close();105 m_File.m_hFile =NULL;106

107 //close the data connection.

108 Close();109

110 m_nTotalBytesSend = 0;111 m_nTotalBytesTransfered = 0;112

113 //change status

114 m_pControlSocket->m_nStatus =STATUS_IDLE;115

116 m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");117

118 //destroy this socket

119 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);120 }121 }122 else

123 {124 m_nTotalBytesTransfered +=dwBytes;125 }126 }127 if (m_nTotalBytesTransfered ==m_nTotalBytesSend)128 {129 //close file.

130 m_File.Close();131 m_File.m_hFile =NULL;132

133 //close the data connection.

134 Close();135

136 m_nTotalBytesSend = 0;137 m_nTotalBytesTransfered = 0;138

139 //change status

140 m_pControlSocket->m_nStatus =STATUS_IDLE;141

142 //tell the client the transfer is complete.

143 m_pControlSocket->SendResponse("226 Transfer complete");144 //destroy this socket

145 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);146 }147 break;148 }149 }150 }

7、OnConnect函数  tcp连接成功时被框架调用的虚函数。

8、OnClose函数 当数据发送完成或者接收完成后被框架调用的虚函数。主要做清理工作。

9、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VC是一种常用的开发平台,可以用来实现各种功能,包括FTP文件下载。在VC中,可以使用WinINet API来实现FTP下载功能。 首先,我们需要在VC中添加相应的头文件和链接库。头文件包括<Windows.h>和<Wininet.h>,链接库为wininet.lib。 接下来,我们需要使用一些关键函数来实现FTP下载。首先是InternetOpen函数,用于初始化WinINet库,并创建一个用于FTP操作的会话句柄。然后,使用InternetOpenUrl函数来打开FTP服务器上的文件,获取到文件的句柄。接着,使用InternetReadFile函数来读取文件内容,并将其写入本地文件中。最后,使用InternetCloseHandle函数关闭句柄,释放资源。 具体实现代码如下所示: ```c++ #include <Windows.h> #include <Wininet.h> void DownloadFTPFile(const char* ftpUrl, const char* localFile) { HINTERNET hInternet = InternetOpen(L"FTPDownloader", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); if (hInternet == NULL) { return; } HINTERNET hFtpSession = InternetOpenUrlA(hInternet, ftpUrl, NULL, 0, INTERNET_FLAG_RELOAD, 0); if (hFtpSession == NULL) { InternetCloseHandle(hInternet); return; } HANDLE hLocalFile = CreateFileA(localFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hLocalFile == INVALID_HANDLE_VALUE) { InternetCloseHandle(hFtpSession); InternetCloseHandle(hInternet); return; } char buffer[4096]; DWORD bytesRead; while (InternetReadFile(hFtpSession, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) { DWORD bytesWritten; WriteFile(hLocalFile, buffer, bytesRead, &bytesWritten, NULL); } CloseHandle(hLocalFile); InternetCloseHandle(hFtpSession); InternetCloseHandle(hInternet); } int main() { const char* ftpUrl = "ftp://example.com/path/to/ftpfile.txt"; const char* localFile = "C:\\localfile.txt"; DownloadFTPFile(ftpUrl, localFile); return 0; } ``` 以上是一个简单的VC程序,用于实现FTP文件下载功能。在使用时,只需将FTP服务器的URL和本地文件的路径传递给DownloadFTPFile函数即可。程序将会从FTP服务器上下载文件,并保存到本地文件中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值