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. 阿里云OSS服务开通STS安全令牌

    搭建直传服务需要完成以下准备工作: 开通OSS,并且创建Bucket. 开通STS服务. 登录 OSS管理控制台. 在OSS概览页中找到基础配置区域,单击 安全令牌,如下图所示: 进入到 安全令牌快捷 ...

  2. left与margin-left区别

    left,right,top,bottom仅对于position:relative|absolute|fixed的元素有意义. <!DOCTYPE html PUBLIC "-//W3 ...

  3. 图片扩展---基于opencv-python实现

    目标: 将一张长方形图片扩展成一张正方形图片,例如: 200x300x3的一张图片扩展成一张300x300x3的图片,填充部分使用白色. 代码: import cv2 import os imglis ...

  4. unity, 对于Debug.Log输出的log,可以双击定位到代码

    unity, 对于Debug.Log输出的log,可以双击定位到代码

  5. Matlab中使用Java api画图图形并保存为jpeg格式

    直接上代码: close all; import java.io.*; import java.awt.*; import java.awt.image.BufferedImage; import j ...

  6. nginx源码学习_源码结构

    nginx的优秀除了体现在程序结构以及代码风格上,nginx的源码组织也同样简洁明了,目录结构层次结构清晰,值得我们去学习.nginx的源码目录与nginx的模块化以及功能的划分是紧密结合,这也使得我 ...

  7. deepin linux下eclipse c/c++ 调试开源代码

    1.deepin linux 下使用eclipse c/c++ 调试2. 编译选项,-g3 -O0,-g3表示输出调试信息,-O0不优化代码(第一个字母o的大写,第二个是数字0) 3.必备环境: gd ...

  8. iOS开发正则表达式的学习

    正则表达式笔记 每天的一小步,知道我在不断进步,这就是我每天的小目标. 这是我的第一篇博客,在工作之余,我会努力地留下些许脚印. 我是一名iOS开发者,对于iOS我仅仅只是一个菜鸟,愿意在此处留下我的 ...

  9. Spring Data Redis 2.x 中 RedisConfiguration 类的新编写方法

    在 Spring Data Redis 1.x 的时候,我们可能会在项目中编写这样一个RedisConfig类: @Configuration @EnableCaching public class ...

  10. @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)什么意思??

    从hibernate2.1开始ehcache已经作为hibernate的默认缓存方案(二级缓存方案 sessionfactory级别), 在项目中有针对性的使用缓存将对性能的提升右很大的帮助. 要使用 ...