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 协议分析的更多相关文章

  1. 实验八 应用层协议Ⅱ-FTP协议分析

    实验八 应用层协议Ⅱ-FTP协议分析 一.实验目的 1.掌握FTP协议的实现原理. 2.了解控制通道和数据通道. 二.实验内容 用WareShark追踪ftp连接. 1.三次握手 2.ftp服务器回发 ...

  2. Java语言实现简单FTP软件------>FTP协议分析(一)

    FTP(File Transfer Protocol)就是文件传输协议.通过FTP客户端从远程FTP服务器上拷贝文件到本地计算机称为下载,将本地计算机上的文件复制到远程FTP服务器上称为上传,上传和下 ...

  3. FTP协议的粗浅学习--利用wireshark抓包分析相关tcp连接

    一.为什么写这个 昨天遇到个ftp相关的问题,关于ftp匿名访问的.花费了大量的脑细胞后,终于搞定了服务端的配置,现在客户端可以像下图一样,直接在浏览器输入url,即可直接访问. 期间不会弹出输入用户 ...

  4. 应用层协议FTP、DNS协议、HTTP协议分析

    分析所用软件下载:Wireshark-win32-1.10.2.exe 一.阅读导览 1.分析FTP协议 2.分析DNS协议 3. 分析HTTP协议 二.分析要求 (1)ftp部分: 学习 Serv- ...

  5. RTSP 协议分析

    RTSP 协议分析1.概述: RTSP(Real Time Streaming Protocol),实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetwor ...

  6. linux 网络协议分析---3

    本章节主要介绍linxu网络模型.以及常用的网络协议分析以太网协议.IP协议.TCP协议.UDP协议 一.网络模型 TCP/IP分层模型的四个协议层分别完成以下的功能: 第一层 网络接口层 网络接口层 ...

  7. 转:LoadRunner自带的协议分析工具

    在做性能测试的时候,协议分析是困扰初学者的难题,不过优秀的第三方协议分析工具还是挺多的,如:MiniSniffer .Wireshark .Ominpeek 等:当然他们除了帮你分析协议之外,还提供其 ...

  8. HTTP协议分析

    一.域名概述 1.域名解析的作用: 主机数量增多时,IP地址不容易记忆,域名方便记忆.域名记忆更加直观. 2.hosts文件 早期通过hosts文件进行域名的解析,Linux系统中hosts文件存放路 ...

  9. RTSP协议分析

    RTSP 协议分析 1.概述:  RTSP(Real Time Streaming Protocol),实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetw ...

随机推荐

  1. android推送方式

    本文介绍在Android中实现推送方式的基础知识及相关解决方案.推送功能在手机开发中应用的场景是越来起来了,不说别的,就我们手机上的新闻客户端就时不j时的推送过来新的消息,很方便的阅读最新的新闻信息. ...

  2. Rational Rose2007具体安装步骤

    学习了UML.那么Rational rose绘图软件当然就是不可缺少的了. 我的电脑是win7 64位的系统.以下的链接是安装软件以及破解方法.该软件是BIN格式的.也就是镜像文件.须要安装一个虚拟驱 ...

  3. excel单元格内插入选择项pass、fail、not support等

    1.点击菜单栏的数据—-->>数据验证 2.选择 序列 在 来源 选项中填入Pass,Fail,On Going,Not Support 3.在选中的单元格并在菜单栏选中 新建规则

  4. Centos7使用LVM扩容磁盘(测试成功)

    1.新增加了一块200G大小的磁盘/dev/sdb fdisk -l 2. pvcreate /dev/sdb 3. pvdisplay 查看添加成功的/dev/sdb的大小为200G 4. vgex ...

  5. Apache配置文件详解

    1.1 ServerRoot 配置 [ServerRoot "" 主要用于指定Apache的安装路径,此选项参数值在安装Apache时系统会自动把Apache的路径写入.Windo ...

  6. ubuntu 新建一个root用户

    1. 新建一个终端(Applications menu -> Accessories -> Terminal), 输入: sudo –s sudo passwd 输入要设置的密码,这样以后 ...

  7. crontab执行脚本与手动执行结果不一致

    反正网上说是环境变量问题,我就直接在脚本第二行加入以下代码: source /etc/profile source ~/.bashrc 问题是解决了!

  8. file、inode在应用层和驱动层之间的联系_转

    转自:http://blog.csdn.net/dreaming_my_dreams/article/details/8272586 应用层和驱动的衔接,一直是一个老大难问题,若弄不清楚,总觉得驱动写 ...

  9. BestCoder Round #93 ABC

    A: 题目大意: 将数组划分成最少的段,每段的数两两不同. 题解:直接用一个map记录一个数是否出现过,贪心的每次取最多个数就好. B: 题目大意: 给出一个0-9组成的字符串,问能否删掉K个数字,使 ...

  10. html 模版

    使用后台开发语言的都很了解语言的动态性给开发带来的好处,PHP,aspx,jsp页面都可以直接使用相应的语法和变量,输出的事就交给解释器或编译器了,用起来方便快捷,但需要额外的解释工作: 例如php模 ...