被動方式 ,連接FTP,然後上傳下載文件。
linux下連接,源碼如下:
FTP.h
[cpp]
#ifndef FTP_H_
#define FTP_H_
#include <sys/types.h>
#include <sys/socket.h>
class CFTP
{
public:
CFTP(void);
~CFTP(void);
//連接ftp服務器
int ftp_connect(const char* ip);
//登錄ftp服務器
int ftp_login(char* user,char* pass);
//顯示當前目錄
int ftp_pwd(char* buff);
//更改目錄
int ftp_cd(char* dir);
//返回上層目錄
int ftp_cdup();
//創建目錄
int ftp_mkdir(char* dir);
//刪除目錄
int ftp_rmdir(char* dir);
//數據傳輸模式
int ftp_setpasv();
//上傳文件
int ftp_upload(char* localfile,char* remotepath,char* remotefilename);
//下載文件
int ftp_download(char* localfile,char* remotefile);
//退出登錄
int ftp_quit();
private:
int m_sockctrl;//控制連接socket
int m_sockdata;//數據連接socket
char m_cmd[256];//存放指令
char m_resp[256];//存放返回語句
char m_ip[64];//保存ip
int ftp_sendcmd();//發送指令
int ftp_checkresp(char expresp);//接收返回狀態,檢測是否成功
int ftp_mkdirSingle(char* dir);
};
#endif
FTP.cpp
[cpp]
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "FTP.h"
using namespace std;
CFTP::CFTP(void)
{
}
CFTP::~CFTP(void)
{
}
int CFTP::ftp_checkresp(char expresp)
{
int len = recv(m_sockctrl,m_resp,256,0);
if(-1 == len)return -1;
m_resp[len]=0;
puts(m_resp);//應該保存ftp運行日志
if(m_resp[0]!=expresp)return -1;
return 0;
}
int CFTP::ftp_sendcmd()
{
int ret = send(m_sockctrl,m_cmd,strlen(m_cmd),0);
if(-1 == ret)return -1;
return 0;
}
int CFTP::ftp_connect(const char* ip)
{
m_sockctrl = socket(AF_INET,SOCK_STREAM,0);
if(0==m_sockctrl)return -1;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(21);
addr.sin_addr.s_addr = inet_addr(ip);
int err = connect(m_sockctrl,(sockaddr*)&addr,sizeof(addr));
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_login(char* user,char* pass)
{
sprintf(m_cmd,"USER %s\r\n",user);
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('3');
if(err)return -1;
sprintf(m_cmd,"PASS %s\r\n",pass);
err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_quit()
{
sprintf(m_cmd,"QUIT\r\n");
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_cd(char* dir)
{
sprintf(m_cmd,"CWD %s\r\n",dir);
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_cdup()
{
sprintf(m_cmd,"CDUP\r\n");
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_pwd(char* buff)
{
sprintf(m_cmd,"PWD\r\n");
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
char* p=m_resp;
while(*p)
{
if(*p++ == '"')
while(*p!='"')
*buff++=*p++;
}
*buff=0;
printf("current work directory is : %s\n",buff);
return 0;
}
int CFTP::ftp_mkdirSingle(char* dir)
{
sprintf(m_cmd,"MKD %s\r\n",dir);
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_mkdir(char* dir)
{
char path[300];
int err = ftp_cd("/");
if(err)return -1;
int i,j;
// printf("strlen(dir):%d",strlen(dir));
for(i=1,j=0;i<strlen(dir);i++) //第一個字節是根目錄
{
path[j++] = dir[i];
if(dir[i]=='/'){
path[j++]='\0';
printf("create :%s\n",path);
err = ftp_mkdirSingle(path);
err = ftp_cd(path);
if(err)return -1;
j=0;
}
}
path[j++]='\0';
sprintf(m_cmd,"MKD %s\r\n",path);
err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_rmdir(char* dir)
{
sprintf(m_cmd,"RMD %s\r\n",dir);
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_upload(char* localfile,char* remotepath,char* remotefilename)
{
ftp_mkdir(remotepath);
int err = ftp_cd(remotepath);
if(err)return -1;
ftp_setpasv();
sprintf(m_cmd,"STOR %s\r\n",remotefilename);
err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('1');
if(err)return -1;
FILE* pf = fopen(localfile,"r");
if(NULL==pf)return -1;
char sendbuf[256];
size_t len = 0;
while((len = fread(sendbuf,1,255,pf))>0)
{
err = send(m_sockdata,sendbuf,len,0);
if(err<0)return -1;
}
close(m_sockdata);
fclose(pf);
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
int CFTP::ftp_setpasv()
{
sprintf(m_cmd,"PASV\r\n");
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
m_sockdata = socket(AF_INET,SOCK_STREAM,0);
unsigned int v[6];
union {
struct sockaddr sa;
struct sockaddr_in in;
} sin;
sscanf(m_resp,"%*[^(](%u,%u,%u,%u,%u,%u",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]);
sin.sa.sa_family = AF_INET;
sin.sa.sa_data[2] = v[2];
sin.sa.sa_data[3] = v[3];
sin.sa.sa_data[4] = v[4];
sin.sa.sa_data[5] = v[5];
sin.sa.sa_data[0] = v[0];
sin.sa.sa_data[1] = v[1];
int on =1;
if (setsockopt(m_sockdata,SOL_SOCKET,SO_REUSEADDR,
(const char*) &on,sizeof(on)) == -1)
{
perror("setsockopt");
close(m_sockdata);
return -1;
}
struct linger lng = { 0, 0 };
if (setsockopt(m_sockdata,SOL_SOCKET,SO_LINGER,
(const char*) &lng,sizeof(lng)) == -1)
{
perror("setsockopt");
close(m_sockdata);
return -1;
}
err = connect(m_sockdata,(sockaddr*)&sin,sizeof(sin));
if(err)return -1;
return 0;
}
int CFTP::ftp_download(char* localfile,char* remotefile)
{
/* sprintf(m_cmd,"TYPE A\r\n",remotefile);
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;*/
ftp_setpasv();
sprintf(m_cmd,"RETR %s\r\n",remotefile);
int err = ftp_sendcmd();
if(err)return -1;
err = ftp_checkresp('1');
if(err)return -1;
FILE* pf = fopen(localfile,"w");
if(NULL==pf)return -1;
char recvbuf[256];
int len = 0;
while((len = recv(m_sockdata,recvbuf,256,0))>0)
{
err = fwrite(recvbuf,len,1,pf);
if(len<0)return -1;
}
close(m_sockdata);
fclose(pf);
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}
測試代碼,主函數 main.cpp:
[cpp]
#include "FTP.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//登錄
CFTP ftpclient;
int err;
err = ftpclient.ftp_connect("192.168.1.63");
if(err){
puts("connect ftp server failed");
exit(-1);
}
puts("connect ok");
err = ftpclient.ftp_login("root","root123");
if(err){
puts("login failed");
exit(-1);
}
puts("login ok");
err = ftpclient.ftp_download("/liuzhe/TestFtp/down.txt","11.txt");
if(err){
puts("download failed");
exit(-1);
}
puts("download ok");
err = ftpclient.ftp_upload("/liuzhe/TestFtp/up.txt","/2012-11-29/aa/bb/cc","22.txt");
if(err){
puts("upload failed");
exit(-1);
} www.2cto.com
puts("upload ok");
err = ftpclient.ftp_quit();
if(err){
puts("quit failed");
exit(-1);
}
puts("you quit");
return 0;
}