FTP协议将使用两条单独的TCP连接,一条专用于发送FTP命令,另一条则专用于传递数据。初始建立连接时,服务器在21号端口上接收来自客户端的命令连接。当需要传送数据时(文件列表、文件数据等),客户端向服务器发出Port命令,并进入监听状态,等待来自服务器的数据连接请求。
首先我们利用VC++ 6.0的AppWizard创建一个基于对话框的应用程序,命名为FtpClientDemo。为
程序生成五个基于CAsyncSocket的新类,这里列出主要代码。
CCommandSocket类的主要代码
void CCommandSocket::OnReceive(int nErrorCode)
{
//这个函数使得服务器的应答消息显示在编辑框上
char buffer=new char[4096];
memset(buffer,0,4096);
this-〉Receive(buffer,1024,0);
//接收应答消息
MessageList+=buffer;
m_ReturnMessage-〉SetWindowText(MessageList);
delete buffer;
}
CFileSocket类的主要代码
void CFileSocket::OnReceive(int nErrorCode)
{
//函数将收到的文件数据写到文件中
if(File= =NULL)
{ File=new CFile();
File-〉Open(FileName,CFile::modeWrite|CFile::modeCreate);
}
charbuffer=new char[4096];
memset(buffer,0,4096);
this-〉Receive(buffer,4096,0);
ReceiveString=buffer;
File-〉Write(ReceiveString,ReceiveString.GetLength( ));
delete buffer;
}
CReceiveSocket类的主要代码
void CReceiveSocket::OnReceive(int nErrorCode)
{
//接收服务器传来的文件列表消息
CString ReceiveString,Temp;
charbuffer=new char[4096];
memset(buffer,0,4096);
this-〉Receive(buffer,4096,0); //接收消息
ReceiveString+=buffer;
delete buffer;
//将文件列表从收到的消息字符串中分离出来,并显示在列表框中
while(!ReceiveString.IsEmpty())
{ int p=ReceiveString.Find("\r\n");
if(p!=-1)
{ Temp=ReceiveString.Left(p);
ReceiveString=ReceiveString.Right(ReceiveString.GetLength()-p-2);
DisplayMessage-〉AddString(Temp);
}
}
}
CPortSocket类主要代码
void CPortSocket::OnAccept(int nErrorCode)
{
//根据不同的标志选择相应的数据连接类,以接受服务器端的数据连接请求
if(Flag= =LISTFILE)
//若
程序要求对目录进行列表,则采用CReceiveSocket类
{DataSocket=new CReceiveSocket(FileList);
this-〉Accept(DataSocket);
}
else if(Flag= =DOWNLOAD)
//若
程序要求
下载文件,则生成CFileSocket类的对象
{FileSocket=new CFileSocket(FileName);
this-〉Accept(FileSocket);
}
}
主对话框类CFtpClient- DemoDlg的主要代码
void CFtpClientDemoDlg::OnFileList()
//响应“文件列表”按钮、列表目录
{ CString Temp;
if(ControlSocket= =NULL)
{
//连接到FTP服务器
ControlSocket=new CCommandSocket(&&m_ReturnMessage);
ControlSocket-〉Create();
m_Server.GetWindowText(Temp);
ControlSocket-〉Connect(Temp,21);
//FTP服务器在21号端口接收连接
}
m_User.GetWindowText(Temp);
Temp="USER "+Temp+"\r\n";
ControlSocket-〉Send(Temp,Temp.GetLength(),0);
//发User命令,验证用户
m_Pass.GetWindowText(Temp); //m_Pass为“口令”编辑框