ftp 协议分析
File Transfer Protocol(文件传输协议)
使用SOCKET实现 FTP的客户端协议规则:
.h
#pragma once
#include <string>
#include <WinSock2.h>
#include <iostream>
#include <atlstr.h>
#include <vector> using namespace std; #pragma comment(lib,"WS2_32.lib") struct StructUrlInfo{
string WebUrl;
string LocUrl;
string Fname;
};
struct ConFtpInfo
{
string Add;
string User;
string Pwd;
int Port;
ConFtpInfo(string m_add,string m_user,string m_pwd,int m_port){
Add=m_add;
User=m_user;
Pwd=m_pwd;
Port=m_port;
}
}; class BZ_Ftp
{
public:
BZ_Ftp(void);
~BZ_Ftp(void); public:
SOCKET controlSocket, dataSocket; public:
bool Start(ConFtpInfo m_ConFtpInfo);
bool RootFileList(ConFtpInfo m_ConFtpInfo,string & name);//获取根目录文件列表
bool GetDirFileList(ConFtpInfo m_ConFtpInfo,string DirName,string &name); //获取传入目录列表
bool GetCurrentpath(ConFtpInfo m_ConFtpInfo,string & name);//返回当前路径 bool DownFile(ConFtpInfo m_ConFtpInfo,string DownUrl,string FileName,string StorageUrl);//下载单个文件
bool GetFileNameSize(ConFtpInfo m_ConFtpInfo,unsigned long &fsize,string DownUrl,string FileName);//获取单个文件大小
bool CreateMultipleDirectory(const CString& szPath);
bool DownAllFile(vector<StructUrlInfo>UpdateInfoVec); unsigned long GetDownFileSize();
unsigned long GFileSize;;
protected:
int getStateCode(char* buf);
bool executeFTPCmd(SOCKET controlSocket, char* buf, int len, int stateCode);
int getPortNum(char* buf);
unsigned long DownFileSize; };
.cpp
#include "StdAfx.h"
#include "BZ_Ftp.h"
#include <vector> #define RECVPACK_SIZE 2048
#define MAXBLOCKSIZE 1024 BZ_Ftp::BZ_Ftp(void)
{
controlSocket=NULL;
dataSocket=NULL;
} BZ_Ftp::~BZ_Ftp(void)
{
closesocket(dataSocket);
closesocket(controlSocket);
WSACleanup();
} bool BZ_Ftp::Start(ConFtpInfo m_ConFtpInfo)
{
WSADATA dat;
SOCKADDR_IN serverAddr;
int dataPort, ret, stateCode;
char buf[100]={0}, sendBuf[1024]={0}; if (WSAStartup(MAKEWORD(2,2),&dat)!=0)
{
cout<<"Init Falied: "<<GetLastError()<<endl;
return false;
} controlSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(controlSocket==INVALID_SOCKET)
{
cout<<"Creating Control Socket Failed: "<<GetLastError()<<endl;
return false;
} serverAddr.sin_family=AF_INET;
serverAddr.sin_addr.S_un.S_addr=inet_addr(m_ConFtpInfo.Add.c_str());
serverAddr.sin_port=htons(m_ConFtpInfo.Port);
memset(serverAddr.sin_zero,0,sizeof(serverAddr.sin_zero)); ret=connect(controlSocket,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
if(ret==SOCKET_ERROR)
{
cout<<"Control Socket connecting Failed: "<<GetLastError()<<endl;
return false;
} cout<<"Control Socket connecting is success."<<endl; recv(controlSocket,buf,100,0); cout<<buf; if(getStateCode(buf) != 220)
{
cout<<"Error: Control Socket connecting Failed"<<endl;
return false;
} memset(buf,0,100);
sprintf(buf,"USER %s\r\n",m_ConFtpInfo.User.c_str());
executeFTPCmd(controlSocket, buf, 100, 331); //331 memset(buf,0,100);
sprintf(buf,"PASS %s\r\n",m_ConFtpInfo.Pwd.c_str());
executeFTPCmd(controlSocket, buf, 100, 230); //230
return true;
} int BZ_Ftp::getStateCode( char* buf )
{
int num=0;
char* p=buf;
while(p != NULL)
{
num=10*num+(*p)-'0';
p++;
if(*p==' '||*p=='-')
{
break;
}
} return num;
} bool BZ_Ftp::executeFTPCmd( SOCKET controlSocket, char* buf, int len, int stateCode )
{
send(controlSocket, buf, len, 0);
memset(buf, 0, len);
recv(controlSocket, buf, 100, 0);
cout<<buf;
if(getStateCode(buf) == stateCode||getStateCode(buf)==226||getStateCode(buf)==250||getStateCode(buf)==150)
{
return true;
}
else
{
cout<<"The StateCode is Error!"<<endl;
return false;
}
} int BZ_Ftp::getPortNum( char* buf )
{
int num1=0,num2=0;
char* p=buf;
int cnt=0;
while( 1 )
{
if(cnt == 4 && (*p) != ',')
{
num1 = 10*num1+(*p)-'0';
}
if(cnt == 5)
{
num2 = 10*num2+(*p)-'0';
}
if((*p) == ',')
{
cnt++;
}
p++;
if((*p) == ')')
{
break;
}
}
cout<<"The data port number is "<<num1*256+num2<<endl;
return num1*256+num2;
} bool BZ_Ftp::RootFileList(ConFtpInfo m_ConFtpInfo, string &strRes )
{
char buffer[1024];
char buf[100];
int dataPort, ret, stateCode;
bool res; return 0;
} bool BZ_Ftp::GetDirFileList( ConFtpInfo m_ConFtpInfo,string DirName,string &strRes )
{
Start(m_ConFtpInfo); char buf[100];
int dataPort;
SOCKADDR_IN serverAddr;
memset(buf,0,100);
sprintf(buf,"PASV\r\n");
executeFTPCmd(controlSocket, buf, 100, 227); dataPort=getPortNum(buf);
//???????socket
dataSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
serverAddr.sin_family=AF_INET;
serverAddr.sin_addr.S_un.S_addr=inet_addr(m_ConFtpInfo.Add.c_str());
serverAddr.sin_port=htons(dataPort); int ret=connect(dataSocket,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
if(ret==SOCKET_ERROR)
{
cout<<"Data Socket connecting Failed: "<<GetLastError()<<endl;
system("pause");
return -1;
} memset(buf,0,100);
sprintf(buf,"CWD %s\r\n",DirName.c_str());//250
executeFTPCmd(controlSocket, buf, 100, 250); memset(buf,0,100);
sprintf(buf,"LIST%s\r\n","");
executeFTPCmd(controlSocket, buf, 100, 150);
memset(buf,0,100);
char buffer[1024];
memset(buffer,0,1024); while(recv(dataSocket,buffer,100,0)){
strRes=strRes.append(buffer);
memset(buffer,0,1024);
} closesocket(dataSocket);
closesocket(controlSocket); return true;
} bool BZ_Ftp::GetCurrentpath( ConFtpInfo m_ConFtpInfo,string & name )
{
Start(m_ConFtpInfo);
char buf[100];
string UrlStr;
memset(buf,0,100);
sprintf(buf,"PWD\r\n","");
executeFTPCmd(controlSocket, buf, 100, 257); UrlStr.append(buf); int index=UrlStr.find('"');
int index2=UrlStr.find('"',index+1); name=UrlStr.substr(index+1,index2-index-1); closesocket(controlSocket); return true;
} bool BZ_Ftp::DownFile( ConFtpInfo m_ConFtpInfo,string DownUrl,string FileName,string StorageUrl )
{
if (!Start(m_ConFtpInfo))
{
return false;
} DownFileSize=0; char buf[100];
char buffer[1024];
memset(buffer,0,1024); int dataPort;
SOCKADDR_IN serverAddr;
memset(buf,0,100);
sprintf(buf,"PASV\r\n"); if(!executeFTPCmd(controlSocket, buf, 100, 227)){ return false;
} dataPort=getPortNum(buf);
//???????socket
dataSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
serverAddr.sin_family=AF_INET;
serverAddr.sin_addr.S_un.S_addr=inet_addr(m_ConFtpInfo.Add.c_str()); //??
serverAddr.sin_port=htons(dataPort); int ret=connect(dataSocket,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
if(ret==SOCKET_ERROR)
{
cout<<"Data Socket connecting Failed: "<<GetLastError()<<endl;
return -1;
} if (DownUrl[0]=='/')
{
DownUrl=DownUrl.substr(1,DownUrl.length());
} string UrlStr;
memset(buf,0,100);
sprintf(buf,"CWD %s\r\n",DownUrl.c_str());
if(!executeFTPCmd(controlSocket, buf, 100, 250)){
return false;
} memset(buf,0,100);
sprintf(buf,"TYPE I\r\n");
if(!executeFTPCmd(controlSocket, buf, 100, 200)){
return false;
} //200 memset(buf,0,100);
sprintf(buf,"RETR %s\r\n",FileName.c_str());
if(!executeFTPCmd(controlSocket, buf, 100, 257)){
return false;
} memset(buf,0,100);
sprintf(buf,"TYPE I\r\n");
if(!executeFTPCmd(controlSocket, buf, 100, 200)){
return false;
} //200 //FileUrlCreat(StorageUrl.c_str());
CreateMultipleDirectory(StorageUrl.c_str()); string m_FileName; if (StorageUrl.length()!=0)
{
if (StorageUrl[StorageUrl.length()-1]=='/')
{
m_FileName=StorageUrl+FileName.c_str(); }else{ m_FileName=StorageUrl+'\\'+FileName.c_str();
} }else{ m_FileName=FileName.c_str();
} FILE * fp = fopen(m_FileName.c_str(),"wb");
int err=GetLastError(); if(NULL == fp )
{
printf("Down Fopen File Err Code:%d",err);
return false;
} int length = 0; while( 0!= (length = recv(dataSocket,buffer,1024,0)))
{
printf("recv %d\n",length); if(length < 0)
{
break;
} int write_length = fwrite(buffer,sizeof(char),length,fp); DownFileSize=DownFileSize+write_length; if (write_length<length)
{ break;
} memset(buffer,0,1024);
} fclose(fp); Sleep(100); return true;
} bool BZ_Ftp::GetFileNameSize( ConFtpInfo m_ConFtpInfo,unsigned long &fsize,string DownUrl,string FileName )
{
Start(m_ConFtpInfo);
char buf[100]; string UrlStr;
memset(buf,0,100);
sprintf(buf,"CWD %s\r\n",DownUrl.c_str());
if(!executeFTPCmd(controlSocket, buf, 100, 257)){
return false;
} memset(buf,0,100);
sprintf(buf,"SIZE %s\r\n",FileName.c_str());
if(!executeFTPCmd(controlSocket, buf, 100, 213)){
return false;
} UrlStr=buf; int index=UrlStr.find(" "); UrlStr=UrlStr.substr(index+1,UrlStr.length()); fsize=atoi(UrlStr.c_str()); return true;
} unsigned long BZ_Ftp::GetDownFileSize()
{
return DownFileSize;
} bool BZ_Ftp::CreateMultipleDirectory( const CString& szPath )
{
CString strDir(szPath);
if (strDir.Right(1) != "\\")
{
strDir.AppendChar('\\');
} vector<CString> vPath;
CString strTemp;
BOOL bSuccess = FALSE; for (int i=0; i<strDir.GetLength(); ++i)
{ if (strDir.GetAt(i) != '\\')
{
strTemp.AppendChar(strDir.GetAt(i));
}
else
{ vPath.push_back(strTemp);
strTemp.AppendChar('\\');
}
} std::vector<CString>::const_iterator vIter; for (vIter = vPath.begin(); vIter != vPath.end(); vIter++)
{
//??CreateDirectory????, ??TRUE,????FALSE
bSuccess = CreateDirectory(*vIter, NULL) ? TRUE : FALSE;
} return bSuccess;
}
调用示例:
int _tmain(int argc, _TCHAR* argv[])
{
ConFtpInfo mConFtpInfo("192.168.1.233","root","root",21); BZ_Ftp mBZ_Ftp; mBZ_Ftp.Start(mConFtpInfo);//连接登录FTP return 0;
}
大家自己可以查阅FPT协议命令 实现更多的功能。
协议重点注意:
21端口 只是ftp登录验证账号密码的端口,验证通过之后,服务端会返回 一个新的数据(也就是端口 num1*256+num2 =新端口) 给客户端 重新连接 ,用这个新的端口就可以进行数据的传输服务。
如有疑问欢迎联系我QQ:1930932008 备注博客园
ftp 协议分析的更多相关文章
- 实验八 应用层协议Ⅱ-FTP协议分析
实验八 应用层协议Ⅱ-FTP协议分析 一.实验目的 1.掌握FTP协议的实现原理. 2.了解控制通道和数据通道. 二.实验内容 用WareShark追踪ftp连接. 1.三次握手 2.ftp服务器回发 ...
- Java语言实现简单FTP软件------>FTP协议分析(一)
FTP(File Transfer Protocol)就是文件传输协议.通过FTP客户端从远程FTP服务器上拷贝文件到本地计算机称为下载,将本地计算机上的文件复制到远程FTP服务器上称为上传,上传和下 ...
- FTP协议的粗浅学习--利用wireshark抓包分析相关tcp连接
一.为什么写这个 昨天遇到个ftp相关的问题,关于ftp匿名访问的.花费了大量的脑细胞后,终于搞定了服务端的配置,现在客户端可以像下图一样,直接在浏览器输入url,即可直接访问. 期间不会弹出输入用户 ...
- 应用层协议FTP、DNS协议、HTTP协议分析
分析所用软件下载:Wireshark-win32-1.10.2.exe 一.阅读导览 1.分析FTP协议 2.分析DNS协议 3. 分析HTTP协议 二.分析要求 (1)ftp部分: 学习 Serv- ...
- RTSP 协议分析
RTSP 协议分析1.概述: RTSP(Real Time Streaming Protocol),实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetwor ...
- linux 网络协议分析---3
本章节主要介绍linxu网络模型.以及常用的网络协议分析以太网协议.IP协议.TCP协议.UDP协议 一.网络模型 TCP/IP分层模型的四个协议层分别完成以下的功能: 第一层 网络接口层 网络接口层 ...
- 转:LoadRunner自带的协议分析工具
在做性能测试的时候,协议分析是困扰初学者的难题,不过优秀的第三方协议分析工具还是挺多的,如:MiniSniffer .Wireshark .Ominpeek 等:当然他们除了帮你分析协议之外,还提供其 ...
- HTTP协议分析
一.域名概述 1.域名解析的作用: 主机数量增多时,IP地址不容易记忆,域名方便记忆.域名记忆更加直观. 2.hosts文件 早期通过hosts文件进行域名的解析,Linux系统中hosts文件存放路 ...
- RTSP协议分析
RTSP 协议分析 1.概述: RTSP(Real Time Streaming Protocol),实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetw ...
随机推荐
- mybatis+oracle的批量插入
// 批量插入,手动控制事务 SqlSession batchSqlSession = null; try { batchSqlSession = sqlSessionTemplate.getSqlS ...
- oracle闪回某个时间段的数据
闪回2013-08-08 08:08:08的数据: insert into table_1 select * from table_2 as of timestamp to_date('2013 ...
- Python 的错误和异常处理
语法错误 Python 的语法错误或者称之为解析错,如下: >>> while True print('Hello world') File "<stdin>& ...
- 通过Spring使用远程访问和web服务
http://docs.huihoo.com/spring/zh-cn/remoting.html Spring2 提供的remote包学习笔记
- ZOJ 3827 Information Entropy (2014牡丹江区域赛)
题目链接:ZOJ 3827 Information Entropy 依据题目的公式算吧,那个极限是0 AC代码: #include <stdio.h> #include <strin ...
- [转]实用教程:搭建FTP服务器以实现局域网飞速传输文件
原文地址:https://www.ithome.com/html/win10/304059.htm 相信很多人都面临过这样的问题:一个局域网下有很多设备,我们想在这些设备之间互传文件,有些文件非常大, ...
- Shiro学习(总结)
声明:本文原文地址:http://www.iteye.com/blogs/subjects/shiro 感谢开涛提供的博文,让我学到了非常多.在这里由衷的感谢你,同一时候我强烈的推荐开涛的博文.他的博 ...
- python升级导致yum命令无法使用的解决
1.报错信息如下: [root@develop bin]# yum [root@develop local]# yum -y install prce There was a problem impo ...
- Phaser 桌面和手机游戏HTML5框架
Phaser是一个流行的2D开源游戏框架,可以用来开发桌面或手机浏览器HTML5游戏,适合侧视或顶视风格: Phaser同时支持Canvas和WebGL渲染引擎,预置了完备的精灵动画.输入 管理.瓦片 ...
- mySQL 开启事件存储过程
怎样在Navicat中设置,是数据库按照记录中的日期更新状态字段 其实这个很常用,比如你网站里的某条记录的日期——比如说数据库中某条活动记录的审核日期字段已经过期,亦即当前时间已经超过审核日期,那么定 ...