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. PHP-深入理解Opcode缓存

    1.什么是opcode缓存? 当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode).Opcode cache的目地是避免重复编译, ...

  2. oc自定义不定参数函数

    -(void)getValueFormConfig:(NSString *)key,... or -(void)getValueFormConfig:(NSString *)key,...NS_REQ ...

  3. spring学习笔记(五)

    1.后置通知 需求:调用相应业务方法后,完成资源的关闭. a. 在beans.xml中配置 .... <beans> <!--配置被代理对象--> <bean id=&q ...

  4. Hive学习 系列博客

    原 Hive作业优化 原 Hive学习六:HIVE日志分析(用户画像) 原 Hive学习五--日志案例分析 原 Hive学习三 原 Hive学习二 原 Hive学习一 博客来源,https://blo ...

  5. 浅谈C语言中断处理机制

    一.中断机制 1.实现中断响应和中断返回 当CPU收到中断请求后,能根据具体情况决定是否响应中断,如果CPU没有更急.更重要的工作,则在执行完当前指令后响应这一中断请求.CPU中断响应过程如下:首先, ...

  6. Java_MD5的使用

    在Java中使用MD5摘要还是很方便的,直接上代码. package com.cxc.nothing; import java.nio.charset.Charset; import java.sec ...

  7. MapReduce源码分析之Task中关于对应TaskAttempt存储Map方案的一些思考

    我们知道,MapReduce有三层调度模型,即Job——>Task——>TaskAttempt,并且: 1.通常一个Job存在多个Task,这些Task总共有Map Task和Redcue ...

  8. UVA 1363 Joseph's Problem 找规律+推导 给定n,k;求k%[1,n]的和。

    /** 题目:Joseph's Problem 链接:https://vjudge.net/problem/UVA-1363 题意:给定n,k;求k%[1,n]的和. 思路: 没想出来,看了lrj的想 ...

  9. jq中写PHP

    var id="$defaultId"; if(!id){ $("#tag_url").addClass("div_display_none" ...

  10. MFC中改变控件的大小和位置(zz)

    用CWnd类的函数MoveWindow()或SetWindowPos()能够改变控件的大小和位置. void MoveWindow(int x,int y,int nWidth,int nHeight ...