// FTPClient.cpp: implementation of the CFTPClient class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SFTP.h"
#include "FTPClient.h"
#include "sftpdoc.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(CSFTPDoc *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[NUMLOGIN][100] = {
// 该数组用来存储防火墙设置,设置USER命令的行参数
{0,LO,3, 1,LO,6, 2,LO,ER}, // 无防火墙
{3,6,3, 4,6,ER, 5,ER,9, 0,LO,12, 1,LO,15, 2,LO,ER}, // 站点主机名
{3,6,3, 4,6,ER, 6,LO,9, 1,LO,12, 2,LO,ER}, // 登录后的USER命令
{7,3,3, 0,LO,6, 1,LO,9, 2,LO,ER}, // 打开代理
{3,6,3, 4,6,ER, 0,LO,9, 1,LO,12, 2,LO,ER},
{6,LO,3, 1,LO,6, 2,LO,ER},
{8,6,3, 4,6,ER, 0,LO,9, 1,LO,12, 2,LO,ER},
{9,ER,3, 1,LO,6, 2,LO,ER},
{10,LO,3, 11,LO,6, 2,LO,ER}
};
if(logontype<0 || logontype>=NUMLOGIN)
return FALSE; // 非法连接类型
// 如果不通过防火墙,直接连接,否则连接到服务器
if(!logontype) {
temp=hostname;
port=hostport;
}
else {
temp=fwhost;
port=fwport;
}
if(hostport!=21)
hostname.Format(hostname+":%d",hostport); // 如果端口不是21,在主机名后面加上端口号
// 建立到远端的连接,并准备好序列化对象
if(!ConnectRemote(temp,port))
return false;
if(!FTPcommand(""))
return FALSE;
// FTPCommand命令用来向服务器发送一条命令,这里发送空行,用来获得基本的
// 服务器信息,对于不同类型的请求发不同的命令序列,通过身份认证
while(1) {
switch(logonseq[logontype][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;
}
// 发出命令并且等待服务器响应
if(!WriteStr(temp)) // 向服务器发送一条命令
return FALSE;
if(!ReadStr()) // 从服务器接收数据
return FALSE;
// 只要下面的响应才是有效的
if(m_fc!=2 && m_fc!=3)
return FALSE;
logonpoint=logonseq[logontype][logonpoint+m_fc-1]; //从数组中获取下一条命令
switch(logonpoint) {
case ER: // ER说明发生错误
m_retmsg.LoadString(IDS_FTPMSG1);
return FALSE;
case LO: // LO说明已经成功登录服务器
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;
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;
// 这一步Socket用于接收数据
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; // 请求二进制模式
m_retmsg.LoadString(IDS_FTPMSG6);
// 通过已经建立的连接获得本地地址
if(!m_Ctrlsok->GetSockName(lhost,localsock))
return FALSE;;
while(1) {
// 把IP地址中的"."转换为","以满足协议要求
if((i=lhost.Find("."))==-1) break;
lhost.SetAt(i,',');
}
// 创建监听Socket并且开始监听(让MFC选择端口),等待服务器的反向连接
if((!sockSrvr.Create(0, SOCK_STREAM, NULL))
|| (!sockSrvr.Listen()))
return FALSE;
if(!sockSrvr.GetSockName(temp,localsock))
return FALSE; // 获取MFC选择的端口
// 将端口号转换为两个字节加到本地IP上
lhost.Format(lhost+",%d,%d", localsock / 256, localsock % 256);
// 向服务器发送PORT反定向命令,并且让服务器按该IP和端口建立反向连接
if(!FTPcommand("PORT "+lhost))
return FALSE; // 发送请求目录命令
if(!WriteStr("LIST") )
return FALSE;
if(!ReadStr())
return FALSE; // 获取RETR/STOR命令的响应
if(!sockSrvr.Accept(datachannel))
return FALSE; // 接收到服务器的反向连接,准备异步
//Socket来接收数据把Socket设为阻塞模式
if((!datachannel.AsyncSelect(0)) ||
(!datachannel.IOCtl(FIONBIO,&lpArgument))) {
m_retmsg.LoadString(IDS_FTPMSG6);
return FALSE;
}
sum = 0;
while(1) { // 从服务器读取数据,并放入动态数组中
TRY {
if(!(num = datachannel.Receive(m_buf.GetData() + sum, BUFSIZE, 0))
|| num == SOCKET_ERROR)
break; // 数据流结束或网络失败
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; // 检查是否成功地完成了列表传输
return TRUE;
}
void CFTPClient::ProcessList()
{
m_pDoc->RemoveAll();
int ndx = 0;
while(GetLine(ndx)){
// m_dlgMsg.TextOut(m_strLine);
m_pDoc->AddLine(m_strLine);
}
}
BOOL CFTPClient::GetLine(int& ndx)
{
m_strLine.Em
没有合适的资源?快使用搜索试试~ 我知道了~
SFTP.rar_FTP CLIENT_sftp_sftp client_文件 传输_文件传输
共37个文件
h:11个
cpp:10个
bmp:3个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 140 浏览量
2022-09-19
14:01:59
上传
评论
收藏 138KB RAR 举报
温馨提示
使用CSocket建立ftp客户端,通过TCP连接进行文件传输
资源推荐
资源详情
资源评论
收起资源包目录
SFTP.rar (37个子文件)
SFTP
SFTPDoc.h 2KB
SFTPDoc.cpp 4KB
SFTP.rc 14KB
FTPSocket.h 1KB
res
SFTP.rc2 396B
bmp00001.bmp 886B
SFTPDoc.ico 1KB
SFTP.ico 1KB
Toolbar.bmp 726B
bitmap1.bmp 3KB
ListItem.h 846B
FTPClient.cpp 11KB
FTPClient.h 1KB
SFTP.dsw 533B
SFTPView.h 2KB
SFTP.opt 150KB
MessageDlg.cpp 1KB
SFTP.ncb 185KB
SFTP.plg 3KB
SFTPView.cpp 7KB
MessageDlg.h 1KB
SFTP.cpp 4KB
StdAfx.cpp 206B
MainFrm.cpp 2KB
SFTP.h 1KB
resource.h 2KB
SFTP.APS 35KB
MainFrm.h 1KB
ListItem.cpp 2KB
StdAfx.h 1KB
SFTP.exe 164KB
SFTP.clw 3KB
FTPSocket.cpp 864B
Debug
SFTP.dsp 5KB
SetupDlg.h 1KB
SetupDlg.cpp 2KB
www.pudn.com.txt 218B
共 37 条
- 1
资源评论
JaniceLu
- 粉丝: 78
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功