写FTP+SSL/TLS(FTPS)比SFTP客户端要麻烦点,虽然有ftplibpp这种优秀的库可以用,但是我发现ftplibpp在对有些FTPS服务端支持的并不是特别好,比如说FTPS+隐式链接时,会出现一些问题,本来想自己改一下ftplibpp但是发现改起来并非容易,索性自己重新了一个ftps客户端。
目前实现了隐式+被动的方式ftps客户端以及sftp客户端。sftp就比较方便libssh2库直接有函数支持非常方便。
注:每台服务器的ftp协议可能会有细微差别,需要自行调整。
l
#include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libssh2.h" #include "libssh2_publickey.h" #include "libssh2_sftp.h" //settings #define IMPLICIT_CONN 0 #define EXPLICIT_CONN 1 //ftp #define FEAT_CMD "FEATrn" #define TYPE_A_CMD "TYPE Arn" #define TYPE_I_CMD "TYPE Irn" #define PASV_CMD "PASVrn" #define PROT_P_CMD "PROT Prn" #define PBSZ_0_CMD "PBSZ 0rn" #define OPTS_MLST "OPTS MLST Size;Modify;Type;Perm;rn" #define SET_UTF8_CMD "OPTS UTF8 ONrn" #define ABOR_CMD "ABORrn" #define SYST_CMD "SYSTrn" #define AUTH_SSL_CMD "AUTH SSLrn" #define AUTH_TLS_CMD "AUTH_TLSrn" //socket #define SETSOCKOPT_OPTVAL_TYPE (void *) //ssl/tls #define _FTPLIB_SSL_CLIENT_METHOD_ TLSv1_2_client_method typedef struct ssl_st SSL; typedef struct ssl_ctx_st SSL_CTX; typedef struct bio_st BIO; typedef struct x509_st X509; //typedef bool (*FtpCallbackCert)(void *arg, X509 *cert); //ftp cmd codemapping #define DOWNLOAD 0 #define UPLOAD 1 #define LS_AL 2 typedef struct _ftps_client_{ SSL* ssl; SSL_CTX* ctx; BIO* sbio; int connfd; int mode; char ip[200]; X509 *cert; }FtpsClient; struct _sftp_client_ { LIBSSH2_SESSION* session; LIBSSH2_SFTP* sftp_session; LIBSSH2_SFTP_HANDLE* sftp_handle; char curdir[2048]; int sockfd; }SftpClient; static int SetConnType(FtpsClient *cli, const int type); static int CloseFtpsDataConn(FtpsClient *cli,FtpsClient *datahandle); int TestConnection(int sock) { struct sockaddr_in addr; socklen_t addr_len = sizeof(addr); int32_t ret = getsockname(sock, (struct sockaddr *)&addr, &addr_len); if(ret == 0) { printf("getsockname succ:%s:%dn", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); } else { printf("getsockname failed,error=%dn", errno); } memset(&addr, 0, sizeof(addr)); ret = getpeername(sock, (struct sockaddr *)&addr, &addr_len); if(ret == 0) { printf("getpeername succ:%s:%dn", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); } else { printf("getpeername failed,error=%dn", errno); return -1; } return 0; } int OpenConnectByIp(const char* ip, const char* port) { struct sockaddr_in sa; // fd_set rSet; int connfd = 0; // int arg = 0; memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr(ip); sa.sin_port = htons(atoi(port)); connfd = socket(AF_INET, SOCK_STREAM, 0); if (connfd < 0) { return -1; } int r = connect(connfd, (struct sockaddr*)&sa, sizeof(sa)); if (r) { perror("sock connect:"); fprintf(stderr, "connect err retcode:%d", r); close(connfd); return -1; } return connfd; } int OpenConnectByHost(FtpsClient *cli, const char *host) { struct sockaddr_in sin; struct linger lng = { 0, 0 }; struct hostent *phe; struct servent *pse; int sControl = 0; int on=1; int ret; char *lhost; char *pnum; memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; lhost = strdup(host); pnum = strchr(lhost,':'); if (pnum == NULL) { if ((pse = getservbyname("ftp","tcp")) == NULL) { perror("getservbyname"); free(lhost); return 0; } sin.sin_port = pse->s_port; } else { *pnum++ = ' '; if (isdigit(*pnum)) sin.sin_port = htons(atoi(pnum)); else { pse = getservbyname(pnum,"tcp"); sin.sin_port = pse->s_port; } } printf("getservbyname successn"); ret = inet_aton(lhost, &sin.sin_addr); if (ret == 0){ if ((phe = gethostbyname(lhost)) == NULL) { perror("gethostbyname"); free(lhost); return -1; } memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length); snprintf(cli->ip,sizeof(cli->ip),"%s",inet_ntoa(*(struct in_addr*)phe->h_addr_list[0]) ); }else snprintf(cli->ip,sizeof(cli->ip),"%s",lhost); free(lhost); sControl = socket(AF_INET, SOCK_STREAM, 0); if (sControl == -1) { perror("socket"); return -1; } if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1) { perror("setsockopt"); return -1; } if (setsockopt(sControl,SOL_SOCKET,SO_LINGER, SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1) { perror("setsockopt"); close(sControl); return -1; } if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1) { perror("connect"); return -1; } printf("socket connect success,connect fd = %dn",sControl); cli->connfd = sControl; return 0; } int InitSSL(FtpsClient *cli) { SSL_library_init(); SSL_load_error_strings(); cli->ctx = SSL_CTX_new(_FTPLIB_SSL_CLIENT_METHOD_()); SSL_CTX_set_verify(cli->ctx, SSL_VERIFY_NONE, NULL); cli->ssl = SSL_new(cli->ctx); return 0; } int NegoSSL(FtpsClient *cli) { int ret = 0; long iErr = 0; char *pErr = NULL; // cli->sbio = BIO_new_socket(cli->connfd, BIO_NOCLOSE); // SSL_set_bio(cli->ssl,cli->sbio,cli->sbio); SSL_set_fd(cli->ssl,cli->connfd); ret = SSL_connect(cli->ssl); printf("ssl_connect %s ret = %d n ",ret==1?"success":"failed",ret); if(ret<=0){ ret = SSL_get_error(cli->ssl, ret); printf("SSL_get_error return code[%d]n",ret); ERR_print_errors_fp(stdout); iErr = ERR_get_error(); pErr = ERR_error_string(ret, NULL); printf("pErr=%sn",pErr); return -1; } cli->cert = SSL_get_peer_certificate(cli->ssl); return 0; } int PrintResp(FtpsClient *cli) { char recvbuf[10240];bzero(recvbuf,sizeof(recvbuf)); SSL_read(cli->ssl, recvbuf, sizeof(recvbuf)); printf("Resp:%s",recvbuf); return 0; } int EnRecv(FtpsClient *cli,char *recvbuf,int recvlen) { return SSL_read(cli->ssl, recvbuf, recvlen); } int EnSend(FtpsClient *cli,const char *sendbuf,int sendlen) { int ret = SSL_write(cli->ssl, sendbuf, sendlen); if(ret <= 0){ printf("SSL_write error"); return -1; } return 0; } int FtpsConn(FtpsClient *cli,const char *host) { int ret = 0; ret = OpenConnectByHost(cli,host); if(ret) return -1; ret = InitSSL(cli); if(ret) return -1; ret = NegoSSL(cli); if(ret) return -1; return 0; } int FtpsLogin(FtpsClient *cli,const char *user,const char *pass) { char buff[10240]; bzero(buff,sizeof(buff)); snprintf(buff,sizeof(buff),"USER %srn",user); EnSend(cli,buff,strlen(buff)); PrintResp(cli); snprintf(buff,sizeof(buff),"PASS %srn",pass); EnSend(cli,buff,strlen(buff)); PrintResp(cli); SetConnType(cli,0); return 0; } int SetConnType(FtpsClient *cli, const int type) { char rbuff[1024]; bzero(rbuff,sizeof(rbuff)); EnSend(cli,FEAT_CMD,strlen(FEAT_CMD)); PrintResp(cli); EnSend(cli,SYST_CMD,strlen(SYST_CMD)); PrintResp(cli); EnSend(cli,SET_UTF8_CMD,strlen(SET_UTF8_CMD)); PrintResp(cli); EnSend(cli,PROT_P_CMD,strlen(PROT_P_CMD)); PrintResp(cli); EnSend(cli,PBSZ_0_CMD,strlen(PBSZ_0_CMD)); PrintResp(cli); if(EXPLICIT_CONN == type){ EnSend(cli,AUTH_SSL_CMD,strlen(AUTH_SSL_CMD)); PrintResp(cli); EnSend(cli,AUTH_TLS_CMD,strlen(AUTH_TLS_CMD)); PrintResp(cli); } return 0; } FtpsClient* OpenFtpsClient(const char *host) { FtpsClient* cli = NULL; int failed = 0; cli = (FtpsClient*)malloc(sizeof(FtpsClient)); if(cli == NULL){ perror("FtpsClient control handle malloc errn"); return NULL; } failed = FtpsConn(cli,host); if(failed){ return NULL; } PrintResp(cli); return cli; } int FtpsOpenPasvSockConn(FtpsClient *cli,FtpsClient *datahandle) { int ret = 0; char host[500]; int port = 0; char *cp,buff[1024],str1[100],str2[100],str3[100]; int v[7]; do{ bzero(buff,sizeof(buff)); bzero(v,sizeof(v)); EnSend(cli,PASV_CMD,strlen(PASV_CMD)); // PrintResp(cli); EnRecv(cli,buff,sizeof(buff)); printf("PASV port :%s",buff); cp = strchr(buff,'('); if (cp == NULL) { printf("PASV return may some error"); return -1; } cp++; sscanf(buff,"%d %s %s %s (%d,%d,%d,%d,%d,%d).",&v[0],str1,str2,str3,&v[1],&v[2],&v[3],&v[4],&v[5],&v[6]); printf("server ip=%sn",cli->ip); port=v[5]*256+v[6]; printf("port=[%d] v[5]=%d,v[6]=%dn",port,v[5],v[6]); snprintf(host,sizeof(host),"%s:%d",cli->ip,port); ret = OpenConnectByHost(datahandle,host); if(ret < 0) printf("Host:%s data sock connect failed,To retry another port...n",host); else break; sleep(5); }while(ret < 0); // TestConnection(datahandle->connfd); return 0; } int FtpsOpenPasvSslConn(FtpsClient *cli,FtpsClient *datahandle) { int success = 0; int failed = 0; char *perr = NULL; datahandle->ssl = SSL_new(cli->ctx); if(datahandle->ssl == NULL){ printf("pdatacli->ssl errn"); close(datahandle->connfd); return -1; } SSL_set_fd(datahandle->ssl,datahandle->connfd); success = SSL_connect(datahandle->ssl); printf(" ssl_connect %s success = %d n ",success==1?"success":"failed",success); if (success != 1){ failed = SSL_get_error(datahandle->ssl, success); perr = ERR_error_string(failed, NULL); printf("ssl connect err:[%s] errcode:[%d]n",perr,failed); return -1; } return 0; } int FtpsOpenPasvDataConn(FtpsClient *cli,FtpsClient *datahandle,const char *cmd) { if(cli == NULL || datahandle == NULL || cmd == NULL){ printf("cli or datahandle or cmd is null pointer"); return -1; } int failed = 0; char buff[1024]; bzero(buff,sizeof(buff)); failed = FtpsOpenPasvSockConn(cli,datahandle); if(failed){ return -1; } EnSend(cli,TYPE_I_CMD,strlen(TYPE_I_CMD)); PrintResp(cli); EnSend(cli,cmd,strlen(cmd)); EnRecv(cli,buff,sizeof(buff)); printf("%sn",buff); if(buff[0] == '5'){ printf("Failed to execute %s n",cmd); printf("%sn",buff); close(datahandle->connfd); return -1; } failed = FtpsOpenPasvSslConn(cli,datahandle); if(failed){ close(datahandle->connfd); return -1; } return 0; } int FtpsAccessDataByPasvMode(FtpsClient *cli,const char *localpath,const char *cmd) { if(cli == NULL || cmd ==NULL) return -1; if(localpath == NULL){ localpath = "./temp.record"; } int failed = 0,len = 0; FtpsClient *datahandle = NULL; FILE *fp = NULL; char buff[10240]; bzero(buff,sizeof(buff)); datahandle = (FtpsClient *)malloc(sizeof(FtpsClient)); if(datahandle == NULL){ perror("datahandle malloc err:"); return -1; } bzero(datahandle,sizeof(FtpsClient)); fp = fopen(localpath,"wb+"); if(fp == NULL){ perror("To open local path error when download file:"); return -1; } failed = FtpsOpenPasvDataConn(cli,datahandle,cmd); if(failed){ printf("Ftps Open Pasv Data Connection errorn"); return -1; } while( (len = SSL_read(datahandle->ssl,buff,sizeof(buff))) > 0){ if (fwrite(buff, 1, len, fp) <= 0) { perror("local path"); break; } bzero(buff,sizeof(buff)); }//end while CloseFtpsDataConn(cli,datahandle); fclose(fp); return 0; } int FtpsGet(FtpsClient *cli,const char *localpath,const char *remotepath) { char cmd[10240]; int failed = 0; char buff[10240]; bzero(cmd,sizeof(cmd)); bzero(buff,sizeof(buff)); snprintf(cmd,sizeof(cmd),"RETR %srn",remotepath); failed = FtpsAccessDataByPasvMode(cli, localpath, cmd); if(failed){ printf("Download remote File[%s] failedn",cmd); return -1; } return 0; } int FtpsSize(FtpsClient *cli,const char *path, size_t *size) { char cmd[256],buff[1024]; size_t resp = 0,sz = 0,rv=0; bzero(cmd,sizeof(cmd)); bzero(buff,sizeof(buff)); snprintf(cmd,sizeof(cmd), TYPE_A_CMD); EnSend(cli,cmd,strlen(cmd)); EnRecv(cli,buff,sizeof(buff)); printf("recv = %sn",buff); bzero(buff,sizeof(buff)); snprintf(cmd,sizeof(cmd),"SIZE %srn",path); EnSend(cli,cmd,strlen(cmd)); EnRecv(cli,buff,sizeof(buff)); printf("recv = %sn",buff); if (sscanf(buff, "%lu %lu", &resp, &sz) == 2) *size = sz; else rv = -1; return rv; } int FtpsDir(FtpsClient *cli,const char *localpath,const char *remotepath) { char cmd[10240]; int failed = 0; bzero(cmd,sizeof(cmd)); snprintf(cmd,sizeof(cmd),"LIST -aL %srn",remotepath); failed = FtpsAccessDataByPasvMode(cli, localpath, cmd); if(failed){ printf("Download remote File[%s] failedn",cmd); return -1; } return 0; } int FtpsChdir(FtpsClient *cli,const char *path) { if(path == NULL) return 0; char buf[256]; int ret = 0; sprintf(buf,"CWD %srn",path); ret = EnSend(cli,buf,strlen(buf)); if(ret <0){ return -1; } bzero(buf,sizeof(buf)); ret = EnRecv(cli,buf,sizeof(buf)); if(ret <=0){ return -1; } printf("%sn",buf); if(buf[0] == '5') return -1; return 0; } int CloseFtpsDataConn(FtpsClient *cli,FtpsClient *datahandle) { EnSend(cli,ABOR_CMD,strlen(ABOR_CMD)); PrintResp(cli); PrintResp(cli); CloseFtpsClient(datahandle); return 0; } int CloseFtpsClient(FtpsClient *cli) { if(cli == NULL) return 0; if(cli->ssl != NULL) SSL_free(cli->ssl); if(cli->ctx != NULL) SSL_CTX_free(cli->ctx); close(cli->connfd); free(cli); return 0; } SftpClient* OpenSftpClient(const char* svrip, const char* svrport) { LIBSSH2_SESSION* session = NULL; int clientfd = 0; int failed = 0, ii = 0, finlen = 0; SftpClient* sclient = NULL; sclient = (SftpClient*)malloc(sizeof(SftpClient)); if (sclient == NULL) { fprintf(stderr, "SftpClient malloc err!"); return NULL; } bzero(sclient, sizeof(SftpClient)); clientfd = OpenConnectByIp(svrip, svrport); if (clientfd < 0) { fprintf(stderr, "OpenConnectByIp errn"); return NULL; } failed = libssh2_init(0); if (failed) { fprintf(stderr, "libssh2 initialization failed (%d)n", failed); close(clientfd); return NULL; } session = libssh2_session_init(); if (!session) { close(clientfd); return NULL; } libssh2_session_set_blocking(session, 1); while ((failed = libssh2_session_handshake(session, clientfd)) == LIBSSH2_ERROR_EAGAIN); if (failed) { fprintf(stderr, "Call libssh2_session_handshake failed,code[%d]n", failed); libssh2_session_free(session); close(clientfd); return NULL; } const char* fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); finlen = strlen(fingerprint); for (ii = 0; ii < finlen; ii++) { fprintf(stderr, "%08x", fingerprint[ii]); } fprintf(stderr, "n"); sclient->session = session; sclient->sockfd = clientfd; return sclient; } int SftpLogin(SftpClient* sclient, const char* user, const char* pswd) { if (sclient == NULL) return -1; int failed = -1; while ((failed = libssh2_userauth_password(sclient->session, user, pswd)) == LIBSSH2_ERROR_EAGAIN); if (failed) { fprintf(stderr, "Authentication by password failed user[%s] pswd[%s] libssh2 failed code[%d]n", user, pswd, failed); return -1; } sclient->sftp_session = libssh2_sftp_init(sclient->session); if (sclient->sftp_session == NULL) { fprintf(stderr, "Unable to init SFTP session ,libssh2 failed code[%lu]n", libssh2_sftp_last_error(sclient->sftp_session)); return -1; } return 0; } int SftpGet(SftpClient* client, const char* dstlocal, const char* srcremote) { if (client == NULL) return -1; FILE* fp = NULL; char buff[1024]; int readbytes = 0; bzero(buff, sizeof(buff)); client->sftp_handle = libssh2_sftp_open(client->sftp_session, srcremote, LIBSSH2_FXF_READ, 0); if (client->sftp_handle == NULL) { fprintf(stderr, "sftp remote path[%s] err! errcode[%lu]n", srcremote, libssh2_sftp_last_error(client->sftp_session)); return -1; } fp = fopen(dstlocal, "wb+"); if (fp == NULL) { fprintf(stderr, "fopen local path[%s] err!n", dstlocal); return -1; } do { readbytes = libssh2_sftp_read(client->sftp_handle, buff, sizeof(buff)); if (!readbytes) { break; } fwrite(buff, 1, readbytes, fp); bzero(buff, sizeof(buff)); } while (1); fclose(fp); return 0; } int SftpPut(SftpClient* client, const char* dstremote, const char* srclocal) { if (client == NULL) return -1; FILE* fp = NULL; char buff[1024]; int localreadbytes = 0; int remotewritebytes = 0; char* curptr = NULL; bzero(buff, sizeof(buff)); fp = fopen(srclocal, "rb"); if (fp == NULL) { fprintf(stderr, "fopen src local path[%s] err!", srclocal); return -1; } client->sftp_handle = libssh2_sftp_open(client->sftp_session, dstremote, LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC, LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH); if (client->sftp_handle == NULL) { fprintf(stderr, "Open remote path[%s] err! %lun", dstremote, libssh2_sftp_last_error(client->sftp_session)); return -1; } do { localreadbytes = fread(buff, 1, sizeof(buff), fp); if (localreadbytes <= 0) { break; } curptr = buff; do { remotewritebytes = libssh2_sftp_write(client->sftp_handle, curptr, localreadbytes); if (remotewritebytes < 0) break; curptr += remotewritebytes; localreadbytes -= remotewritebytes; } while (localreadbytes); } while (remotewritebytes > 0); return 0; } int SftpDir(SftpClient* client, const char* path) { if (client == NULL) return -1; LIBSSH2_SFTP_ATTRIBUTES attrs; int success = 0; char entry[1024]; char file[1024]; bzero(entry, sizeof(entry)); bzero(file, sizeof(file)); client->sftp_handle = libssh2_sftp_opendir(client->sftp_session, path); if (client->sftp_handle == NULL) { fprintf(stderr, "sftp opendir err!n"); return -1; } while (1) { success = libssh2_sftp_readdir_ex(client->sftp_handle, file, sizeof(file), entry, sizeof(entry), &attrs); if (success) { if (entry[0] != ' ') { if (!strcmp(file, ".") || !strcmp(file, "..")) { continue; } if (S_ISREG(attrs.permissions)) { fprintf(stderr, "file[%s]n", file); } else if (S_ISDIR(attrs.permissions)) { fprintf(stderr, "dir[%s]n", file); } } } else break; bzero(entry, sizeof(entry)); bzero(file, sizeof(file)); }//end while 1 ... if (0 != libssh2_sftp_closedir(client->sftp_handle)) { fprintf(stderr, "sftp close dir err!n"); return -1; } client->sftp_handle = NULL; return 0; } int SftpChdir(SftpClient* client, const char* path) { if (client == NULL) return -1; return 0; } int CloseSftpClient(SftpClient* client) { if (client == NULL) return 0; if (client->sftp_handle != NULL) libssh2_sftp_close(client->sftp_handle); if (client->sftp_session != NULL) libssh2_sftp_shutdown(client->sftp_session); if (client->sftp_session != NULL) libssh2_session_disconnect(client->session, "To shutdown sftp clientn"); if (client->sftp_session != NULL) libssh2_session_free(client->session); client->session = NULL; close(client->sockfd); return 0; } #ifdef _SFTP_CLIENT_TEST_ int main() { const char* ip = "127.0.0.1"; const char* port = "8092"; char user[20] = "root"; char pswd[50] = "root"; int ret = 0; SftpClient* sftp = OpenSftpClient(ip, port); if (sftp == NULL) { fprintf(stderr, "OpenSftpClient err ip[%s],port[%s] n", ip, port); return -1; } ret = SftpLogin(sftp, user, pswd); ret = SftpDir(sftp, "./data_iftp/"); ret = SftpGet(sftp, "/home/fis/guoxf/债券收盘收益率曲线报表_20220307.csv", "/data_iftp/债券收盘收益率曲线报表_20220307.csv"); CloseSftpClient(sftp); return 0; } #elif _FTPS_CLIENT_TEST_ //iconv #define TO_UTF8 "UTF-8//IGNORE" #define TO_GB2312 "GB2312//IGNORE" #define FROM_UTF8 "UTF-8" #define FROM_GB2312 "GB2312" #define CMDS_MAX_MSG_GBK_SIZE 16384 #define CMDS_MAX_MSG_UTF8_SIZE 32768 int iconv_gbk_to_utf8(char* inbuf) { iconv_t cd; int ret; size_t ileft, oleft; char* fptr; char* tptr; int count; char iconv_tmp_string[CMDS_MAX_MSG_UTF8_SIZE]; cd = iconv_open(TO_UTF8, FROM_GB2312); if (cd == (iconv_t)-1) { fprintf(stdout, "iconv_open failed[%d]n", errno); return 0; } memset(iconv_tmp_string, 0, CMDS_MAX_MSG_UTF8_SIZE); ileft = strlen(inbuf); oleft = CMDS_MAX_MSG_UTF8_SIZE; tptr = &iconv_tmp_string[0]; fptr = inbuf; if ((ret = iconv(cd, &fptr, &ileft, &tptr, &oleft)) != 0) { fprintf(stdout, "iconv errno code=%d.n", errno); fprintf(stdout, "after iconv tmp_string=%sn", iconv_tmp_string); //有时候会出现11的错误码,可忽略掉 if (errno != 0 && errno != 2 && errno != 11 && errno != 10 && errno != 84) { fprintf(stdout, "iconv error use original gb2312n"); iconv_close(cd); return 0; } } iconv_close(cd); count = strlen(iconv_tmp_string); memmove(inbuf, iconv_tmp_string, count); inbuf[count] = ' '; return 1; } int main() { const char *host = "127.0.0.1:1250"; const char *user = "root"; const char *pass = "root"; int failed = 0; size_t size = 0; char remotepath[20000]; char remotedir[10000]; bzero(remotepath,sizeof(remotepath)); bzero(remotedir,sizeof(remotedir)); snprintf(remotepath,sizeof(remotepath),"/基准数据报表/债券收盘估值/债券收盘估值_20220507.csv"); iconv_gbk_to_utf8(remotepath); snprintf(remotedir,sizeof(remotedir),"/基准数据报表/债券收盘估值"); iconv_gbk_to_utf8(remotedir); FtpsClient *cli = NULL; cli = OpenFtpsClient(host); if(cli == NULL) return -1; failed = FtpsLogin(cli,user,pass); if(failed) return -1; failed = FtpsGet(cli,"./test.csv",remotepath); if(failed) return -1; failed = FtpsDir(cli,NULL,remotedir); if(failed) return -1; FtpsChdir(cli,remotedir); snprintf(remotepath,sizeof(remotepath),"/基准数据报表/债券收盘估值/债券收盘估值_20220509.csv"); iconv_gbk_to_utf8(remotepath); failed = FtpsGet(cli,"./test.csv",remotepath); if(failed) return -1; failed = FtpsSize(cli,remotepath, &size); if(failed) return -1; CloseFtpsClient(cli); return 0; } #endif
编译命令:
cc ftpclient.c -lssl -lssh2 -lcrypto -lz -oftpclient -g



