ftpclient ftp客户端源码

来源:互联网 发布:德国网络布线 编辑:程序博客网 时间:2024/05/21 05:04

ftp客户端自己搭建,已经测试在linux和windos下面的ftpsvr可以连接成功和传输图像,

出现windos上次图片失败的问题, windos下文件名称不能包含 

“?”、“、”、“╲”、“/”、“*”、““”、“”“、“<”、“>”、“|”。:

(需要源码和测试信息联系QQ:123011785)

经过修改测试相对稳定,下面附加代码信息

ftp.h源码:

#ifndef __VSS_FTP_CLIENT_H__#define __VSS_FTP_CLIENT_H__#include <stdlib.h>#include <fcntl.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <arpa/inet.h>#include <stdio.h>#include <netdb.h>#include <string.h>#include <sys/stat.h>#include <sys/statfs.h>#include <errno.h>#include <assert.h>#include <netinet/in.h>#include <dirent.h>#include <ctype.h>using namespace std;#define bb_perror_msg(x) printf(x)#define bb_msg_read_error "Error: bb_msg_read_error"#define bb_msg_write_error "Error: bb_msg_write_error"#define NOT_LONE_DASH(s) ((s)[0] != '-' || (s)[1])#define bb_perror_msg_and_die printf#define bb_error_msg_and_die printf#define bb_perror_nomsg_and_die() assert(0);//#define TRACE() printf("%s %d\n", __FUNCTION__, __LINE__);#define OFF_FMT "l"typedef struct len_and_sockaddr {socklen_t len;union {struct sockaddr sa;struct sockaddr_in sin;};} len_and_sockaddr;typedef struct ftp_host_info_s {const char *user;const char *password;struct len_and_sockaddr *lsa;} ftp_host_info_t;#ifdef  __cplusplusextern "C" {#endifint xatou(char *buf);int xatoul_range(char *buf, int low, int top);len_and_sockaddr *xhost2sockaddr(const char *ip_addr, int port);char* sockaddr2str(const struct sockaddr *sa, int flags);char* xmalloc_sockaddr2dotted(const struct sockaddr *sa);int xopen3(const char *pathname, int flags, int mode);int xopen(const char *pathname, int flags);void safe_fclose(FILE *control_stream);ssize_t safe_read(int fd, void *buf, size_t count);ssize_t safe_write(int fd, const void *buf, size_t count);size_t full_write(int fd, const void *buf, size_t len);off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size);off_t bb_copyfd_eof(int fd1, int fd2);void ftp_die(const char *msg, const char *remote);int ftpcmd(const char *s1, const char *s2, FILE *stream, char *buf);void set_nport(len_and_sockaddr *lsa, unsigned port);int xconnect_ftpdata(ftp_host_info_t *server, char *buf);void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen);int xsocket(int domain, int type, int protocol);int xclose(int s);int xconnect_stream(const len_and_sockaddr *lsa);FILE *ftp_login(ftp_host_info_t *server);int ftp_mkdir(FILE *control_stream, const char *FoldName);int ftp_cd(FILE *control_stream, const char *FoldName);int ftp_send(ftp_host_info_t *server, FILE *control_stream,const char *server_path, char *local_path);int ftp_quit(FILE *control_stream);//int main(void);#ifdef __cplusplus}#endif#endif

ftp.c源码如下:

#include "ftpclient.h"#if 0enum {LSA_SIZEOF_SA = sizeof(union {struct sockaddr sa;struct sockaddr_in sin;})};#endiftypedef structftpmissions{int currmission_id;int len_missionlist;}ftpmissions_t;typedef structftpbackupmission_info{int currfilelist_id;int len_filelist;}ftpbackupmission_info_t;int xatou(char *buf){char c;int i;int j = 0;int retval = 0;char mod[3] = {1, 10, 100};int len = strlen(buf);if ( (!len)||(len > 3) ){return -1;}for (i = len - 1; i >= 0; i--){c = buf[i];retval += atoi(&c)*mod[j++];}return retval;}int xatoul_range(char *buf, int low, int top){int retval = xatou(buf);if (retval < low){retval = low;}if (retval > top){retval = top;}//printf("buf = %s\n", buf);//printf("###retval = %d\n", retval);return retval;}len_and_sockaddr *xhost2sockaddr(const char *ip_addr, int port){int rc;len_and_sockaddr *r = NULL;struct addrinfo *result = NULL;struct addrinfo hint;memset(&hint, 0, sizeof(hint));hint.ai_family = AF_INET;hint.ai_socktype = SOCK_STREAM;rc = getaddrinfo(ip_addr, NULL, &hint, &result);if (rc||!result){free(r);r = NULL;return r;}r = (len_and_sockaddr *)malloc(4 + result->ai_addrlen);if (r == NULL){return NULL;}r->len = result->ai_addrlen;memcpy(&r->sa, result->ai_addr, result->ai_addrlen);r->sin.sin_port = htons(port);freeaddrinfo(result);return r;}/******************************************************************/#define IGNORE_PORT NI_NUMERICSERVchar* sockaddr2str(const struct sockaddr *sa, int flags){char host[128];char serv[16];int rc;socklen_t salen;//salen = LSA_SIZEOF_SA;salen = sizeof(sockaddr);rc = getnameinfo(sa, salen,host, sizeof(host),/* can do ((flags & IGNORE_PORT) ? NULL : serv) but why bother? */serv, sizeof(serv),/* do not resolve port# into service _name_ */flags | NI_NUMERICSERV);if (rc)return NULL;if (flags & IGNORE_PORT)return strdup(host);/* For now we don't support anything else, so it has to be INET *//*if (sa->sa_family == AF_INET)*/char *retmsg = (char *)malloc(2048);memset(retmsg, 0, 2048);sprintf(retmsg, "%s:%s", host, serv);return retmsg;/*return xstrdup(host);*/}char* xmalloc_sockaddr2dotted(const struct sockaddr *sa){return sockaddr2str(sa, NI_NUMERICHOST);}int xopen3(const char *pathname, int flags, int mode){int ret;ret = open(pathname, flags, mode);if (ret < 0) {bb_perror_msg_and_die("can't open '%s'", pathname);}return ret;}int xopen(const char *pathname, int flags){return xopen3(pathname, flags, 0666);}void safe_fclose(FILE *control_stream){if (control_stream != NULL){printf("+++++++++close ftp control_stream!!!!\n\n");fclose(control_stream);control_stream = NULL;}}ssize_t safe_read(int fd, void *buf, size_t count){ssize_t n;do {n = read(fd, buf, count);} while (n < 0 && errno == EINTR);return n;}ssize_t safe_write(int fd, const void *buf, size_t count){ssize_t n;do {n = write(fd, buf, count);} while (n < 0 && errno == EINTR);return n;}size_t full_write(int fd, const void *buf, size_t len){ssize_t cc;ssize_t total;total = 0;while (len) {cc = safe_write(fd, buf, len);if (cc < 0)return cc;/* write() returns -1 on failure. */total += cc;buf = ((const char *)buf) + cc;len -= cc;}return total;}off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size){int status = -1;off_t total = 0;char buffer[BUFSIZ];if (src_fd < 0)goto out;if (!size) {size = BUFSIZ;status = 1; /* copy until eof */}while (1) {ssize_t rd;rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size);if (!rd) { /* eof - all done */status = 0;break;}if (rd < 0) {bb_perror_msg(bb_msg_read_error);break;}/* dst_fd == -1 is a fake, else... */if (dst_fd >= 0) {ssize_t wr = full_write(dst_fd, buffer, rd);if (wr < rd) {bb_perror_msg(bb_msg_write_error);break;}}total += rd;if (status < 0) { /* if we aren't copying till EOF... */size -= rd;if (!size) {/* 'size' bytes copied - all done */status = 0;break;}}}out:return status ? -1 : total;}off_t bb_copyfd_eof(int fd1, int fd2){return bb_full_fd_action(fd1, fd2, 0);}/******************************************************************/void ftp_die(const char *msg, const char *remote){/* Guard against garbage from remote server */const char *cp = remote;while (*cp >= ' ' && *cp < '\x7f') cp++;bb_error_msg_and_die("unexpected server response%s%s: %.*s\n",msg ? " to " : "", msg ? msg : "",(int)(cp - remote), remote);//assert(0);}int ftpcmd(const char *s1, const char *s2, FILE *stream, char *buf){unsigned n;if (s1) {if (s2) {fprintf(stream, "%s %s\r\n", s1, s2);} else {fprintf(stream, "%s\r\n", s1);}}do {char *buf_ptr;if (fgets(buf, 510, stream) == NULL) {bb_perror_msg_and_die("fgets");return -1;}buf_ptr = strstr(buf, "\r\n");if (buf_ptr) {*buf_ptr = '\0';}} while (!isdigit(buf[0]) || buf[3] != ' ');buf[3] = '\0';n = xatou(buf);buf[3] = ' ';return n;}void set_nport(len_and_sockaddr *lsa, unsigned port){if (lsa->sa.sa_family == AF_INET) {lsa->sin.sin_port = port;return;}/* What? UNIX socket? IPX?? :) */}int xconnect_ftpdata(ftp_host_info_t *server, char *buf){char *buf_ptr;unsigned short port_num;//printf("buf = %s\n", buf);/* Response is "NNN garbageN1,N2,N3,N4,P1,P2[)garbage] * Server's IP is N1.N2.N3.N4 (we ignore it) * Server's port for data connection is P1*256+P2 */buf_ptr = strrchr(buf, ')');if (buf_ptr) *buf_ptr = '\0';buf_ptr = strrchr(buf, ',');*buf_ptr = '\0';port_num = xatoul_range(buf_ptr + 1, 0, 255);buf_ptr = strrchr(buf, ',');*buf_ptr = '\0';port_num += xatoul_range(buf_ptr + 1, 0, 255) * 256;//printf("#### port_num = %d\n", port_num);set_nport(server->lsa, htons(port_num));return xconnect_stream(server->lsa);}void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen){if (connect(s, s_addr, addrlen) < 0) {if (s_addr->sa_family == AF_INET)bb_perror_msg_and_die("%s (%s)\n","cannot connect to remote host",inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr));bb_perror_msg_and_die("cannot connect to remote host\n");//assert(0);}}// Die with an error message if we can't open a new socket.int xsocket(int domain, int type, int protocol){int r = socket(domain, type, protocol);if (r < 0) {/* Hijack vaguely related config option */#if ENABLE_VERBOSE_RESOLUTION_ERRORSconst char *s = "INET";if (domain == AF_PACKET) s = "PACKET";if (domain == AF_NETLINK) s = "NETLINK";USE_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)bb_perror_msg_and_die("socket(AF_%s)", s);#elsebb_perror_msg_and_die("socket");#endif}return r;}int xclose(int s){if (s > 0){close(s);s = -1;}}int xconnect_stream(const len_and_sockaddr *lsa){int fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0);xconnect(fd, &lsa->sa, lsa->len);return fd;}FILE *ftp_login(ftp_host_info_t *server){FILE *control_stream;char buf[512];int login_fd;/* Connect to the command socket */login_fd = xconnect_stream(server->lsa);if(login_fd == -1)return NULL;control_stream = fdopen(login_fd, "r+");if (control_stream == NULL) {xclose(login_fd);/* fdopen failed - extremely unlikely */bb_perror_nomsg_and_die();return NULL;}if (ftpcmd(NULL, NULL, control_stream, buf) != 220) {ftp_die(NULL, buf);safe_fclose(control_stream);return NULL;}/*  Login to the server */switch (ftpcmd("USER", server->user, control_stream, buf)) {case 230:break;case 331:if (ftpcmd("PASS", server->password, control_stream, buf) != 230) {ftp_die("PASS", buf);safe_fclose(control_stream);return NULL;}break;default:{ftp_die("USER", buf);safe_fclose(control_stream);return NULL;}}if(ftpcmd("TYPE I", NULL, control_stream, buf) == -1){safe_fclose(control_stream);return NULL;}return control_stream;}int ftp_mkdir(FILE *control_stream, const char *FoldName){if (strlen(FoldName) <= 0){return -1;}char buf[512];int response = ftpcmd("MKD", FoldName, control_stream, buf);if(response != 257){//printf("MKD1111111111111111111111:%d\n", response);ftp_die("MKD", buf);return -1;}//printf("MKD2222222222222222222:%d\n", response);return 0;}int ftp_cd(FILE *control_stream, const char *FoldName){if (strlen(FoldName) <= 0){return -1;}char buf[512];int response = ftpcmd("CWD", FoldName, control_stream, buf);if(response != 250){//printf("CWD1111111111111111111111response:%d\n", response);ftp_die("CWD", buf);return -1;}//printf("CWD2222222222222222222response:%d\n", response);return 0;}int ftp_send(ftp_host_info_t *server, FILE *control_stream,const char *server_path, char *local_path){struct stat sbuf;char buf[512];int fd_data;int fd_local;int response;/*  Connect to the data socket */if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {ftp_die("PASV", buf);return -1;}fd_data = xconnect_ftpdata(server, buf);if(fd_data == -1)return -1;/* get the local file */fd_local = STDIN_FILENO;if (NOT_LONE_DASH(local_path)) {fd_local = xopen(local_path, O_RDONLY);while(fd_local == -1){xclose(fd_local);sleep(1);fd_local = xopen(local_path, O_RDONLY);}fstat(fd_local, &sbuf);sprintf(buf, "ALLO %"OFF_FMT"u", sbuf.st_size);response = ftpcmd(buf, NULL, control_stream, buf);switch (response) {case 200:case 202:break;default:{xclose(fd_data);xclose(fd_local);ftp_die("ALLO", buf);return -1;}}}response = ftpcmd("STOR", server_path, control_stream, buf);switch (response) {case 125:case 150:break;default:{xclose(fd_data);xclose(fd_local);ftp_die("STOR", buf);return -1;}}/* transfer the file  */ftpmissions_t missionlist={0,0};ftpbackupmission_info_t filelist={0,0};do{do{if (bb_copyfd_eof(fd_local, fd_data) == -1) {/* close it all down */xclose(fd_data);xclose(fd_local);return -1;//exit(EXIT_FAILURE);  }}while(filelist.currfilelist_id++<=filelist.len_filelist);}while (missionlist.currmission_id++<=missionlist.len_missionlist);/* close it all down */close(fd_data);close(fd_local);if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {ftp_die("close", buf);return -1;}return EXIT_SUCCESS;}int ftp_quit(FILE *control_stream){if (control_stream == NULL){return -1;}char buf[512];ftpcmd("QUIT", NULL, control_stream, buf);safe_fclose(control_stream);return 0;}#if 1int main(void){//const char *port = "ftp";FILE *control_stream;ftp_host_info_t *server;char local_path[128];char server_path[128];server = malloc(sizeof(*server));if (server == NULL){return -1;}server->user = "ftpsvr";server->password = "123456";server->lsa = xhost2sockaddr("192.168.1.8", 21);printf("Connecting to %s (%s)\n", "192.168.1.8",xmalloc_sockaddr2dotted(&server->lsa->sa));control_stream = ftp_login(server);int iret = ftp_cd(control_stream, "screenshort10");if (iret < 0){ftp_mkdir(control_stream, "screenshort10");ftp_cd(control_stream, "screenshort10");}while(1){sprintf(local_path,  "%s", "100421133604-000-3-1.jpg");sprintf(server_path, "%s", "100421133604-000-3-1.jpg");if(ftp_send(server, control_stream, server_path, local_path)==-1){fclose(control_stream);control_stream = NULL;printf("\nConnecting to %s (%s)\n", "192.168.1.8",xmalloc_sockaddr2dotted(&server->lsa->sa));while(control_stream == NULL){server->user = "ftpsvr";server->password = "123456";server->lsa = xhost2sockaddr("192.168.1.8", 21);control_stream = ftp_login(server);}}else{//fprintf(stdout,"%s upload success\n",local_path);}ftp_quit(control_stream);break;}return 0;}#endif



原创粉丝点击