FTP_client c program

本文介绍了一个简单的FTP客户端程序实现,包括连接、文件上传与下载等功能。该程序使用C语言编写,涉及socket编程、文件操作等关键技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

/*

* Copyright (c) www.chinaunix.net(ldap)

* All rights reserved.

*

* Filename        : ftp.c

*/

#include <stdio.h>;

#include <sys/stat.h>;

#include <fcntl.h>;

#include <stdlib.h>;

#include <sys/time.h>;

#include <time.h>;

#include <unistd.h>;

#include <string.h>;

#include <signal.h>;

#include <errno.h>;

#include <sys/types.h>;

#include <sys/socket.h>;

#include <netinet/in.h>;

#include <arpa/inet.h>;

#define FTP_PORT    21

#define MAXBACKLOG  30

#define TIMEOUT     8

extern void *ssignal (int signo, void *func);

static int saferecv(int fd, char *buf, int size);

static int safesend(int fd, char *buf, int size);

static int connect_ftp(char *ip, char *username, char *password);

static int create_dataconn(int sockfd, char *localip, int localport);

static void set_timeout();

static void unset_timeout();

static void sig(int signo)

{

        put_log("ERROR:capture signal %d\n", signo);

}

static void set_timeout()

{

        struct itimerval value;

        ssignal(SIGALRM, sig);

        value.it_value.tv_sec  = TIMEOUT;

        value.it_value.tv_usec = 0;

        value.it_interval      = value.it_value;

        setitimer(ITIMER_REAL, &value, NULL );

}

static void unset_timeout()

{

        struct itimerval value;

        ssignal(SIGALRM, SIG_IGN);

        value.it_value.tv_sec  = 0;

        value.it_value.tv_usec = 0;

        value.it_interval      = value.it_value;

        setitimer(ITIMER_REAL, &value, NULL );

}

static int saferecv(int fd, char *buf, int size)

{

        int ret;

        set_timeout();

        if ((ret = recv(fd, buf, size, 0)) < 0) {

                put_log("ERROR:recv,%s\n", strerror(errno));

                unset_timeout();

                return -1;

        }

        unset_timeout();

        return ret;

}

static int safesend(int fd, char *buf, int size)

{

        int ret;

        set_timeout();

        if ((ret = send(fd, buf, size, 0)) < 0) {

                put_log("ERROR:send,%s\n", strerror(errno));

                unset_timeout();

                return -1;

        }

        unset_timeout();

        return ret;

}

static int connect_ftp(char *ip, char *username, char *password)

{

        int          sockfd, port;

        struct sockaddr_in server;

        char         buff[1024];

        port = FTP_PORT;

        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

                put_log("ERROR:socket,%s\n", strerror(errno));

                return -1;

        }

        server.sin_family = AF_INET;

        server.sin_port = htons((unsigned short)port);

        server.sin_addr.s_addr = inet_addr(ip);

        set_timeout();

        if (connect(sockfd, (struct sockaddr *)&server , sizeof(server)) == -1)

        {

                put_log("ERROR:socket,%s\n", strerror(errno));

                unset_timeout();

                alarm(0);

                signal(SIGALRM, SIG_IGN);

                close(sockfd);

                return -1;

        }

        unset_timeout();

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        if (strstr(buff, "220") == NULL) {

                put_log("ERROR:connection refused by remote ftp server\n");

                close(sockfd);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        sprintf(buff, "USER %s\r\n", username);

        if (safesend(sockfd, buff, strlen(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        if (strstr(buff, "331") == NULL) {

                put_log("ERROR:connection refused by remote ftp server\n");

                close(sockfd);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        sprintf(buff, "PASS %s\r\n", password);

        if (safesend(sockfd, buff, strlen(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        if (strstr(buff, "230") == NULL) {

                put_log("ERROR:username and password not match\n");

                close(sockfd);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        sprintf(buff, "SYST\r\n");

        if (safesend(sockfd, buff, strlen(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        sprintf(buff, "TYPE I\r\n");

        if (safesend(sockfd, buff, strlen(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        return sockfd;

}

static int create_dataconn(int sockfd, char *localip, int localport)

{

        int          on = 1, l_i;

        int          localsock;

        struct       sockaddr_in localserver;

        if((localsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

                put_log("ERROR:socket,%s\n", strerror(errno));

                close(sockfd);

                return -1;

        }

        if (setsockopt(localsock, SOL_SOCKET, SO_REUSEADDR,

                (char *)&on, sizeof(on)) == -1) {

                put_log("ERROR:setsockopt,%s\n", strerror(errno));

                close(sockfd);

                close(localsock);

                return -1;

        }

        localserver.sin_family = AF_INET;

        localserver.sin_addr.s_addr = INADDR_ANY;

        localserver.sin_port = htons((unsigned short)localport);

        if ((bind(localsock, (struct sockaddr *)&localserver, sizeof(localserver)) == -1) ||

                (listen(localsock, MAXBACKLOG) == -1)) {

                put_log("ERROR:%s\n", strerror(errno));

                put_log("ERROR:Unable to establish port %d connection\n", localport % 65536);

                close(sockfd);

                close(localsock);

                return -1;

        }

        if (get_localip(localip) == -1) {

                put_log("ERROR:get_localip\n");

                close(sockfd);

                close(localsock);

                return -1;

        }

        for (l_i = 0; l_i < strlen (localip); l_i++)

                if (localip[l_i] == '.')

                        localip[l_i] = ',';

        return localsock;

}

int download(char *ftpserver, char *username, char *password, char *filename)

{

        int          sockfd, localsock, dsock;

        int          localport, len, i, j, k;

        int          fd;

        struct sockaddr_in remote;

        int                remote_len;

        char         buff[1024];

        char         localip[256] = "10.10.17.169";

        char         temp[32];

        int dwRead;

        int dw;

        if ((sockfd = connect_ftp(ftpserver, username, password)) == -1) {

                put_log("ERROR:connect_ftp\n");

                return -1;

        }

        /*get random seed*/

        srand ((double) time (NULL) * 1000000);

        /*use random number as port for ftpdata bind*/

        localport = (rand () % 20000) + 2000;

        if ((localsock = create_dataconn(sockfd, localip, localport)) == -1) {

                put_log("ERROR:connect_ftp\n");

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        sprintf(buff, "PORT %s,%d,%d\r\n", localip, localport / 256, localport % 256);

        if (safesend(sockfd, buff, strlen(buff)) < 0)

        {

                close(sockfd);

                close(localsock);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        if (strstr(buff, "200") == NULL) {

                put_log("ERROR:Unable to get valid data\n");

                close(sockfd);

                close(localsock);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        sprintf (buff, "SIZE %s\r\n", filename);

        if (safesend (sockfd, buff, strlen(buff)) < 0)

        {

                close (sockfd);

                close (localsock);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                close(localsock);

                return -1;

        }

        if (strstr(buff, "550") != NULL) {

                put_log("ERROR:not exist upgrade package\n");

                close(sockfd);

                close(localsock);

                return -1;

        }

        len = strlen(buff);

        for (i = 0; i < len; i++)

        {

                if (buff[i] == ' ')

                {

                        k = 0;

                        for (j = i + 1; j < len; j++)

                        {

                                if ((buff[j] >;= 48) && (buff[j] <= 57))

                                        temp[k] = buff[j];

                                k++;

                        }

                        break;

                }

        }

        len = atoi (temp);

        memset(buff, 0, sizeof(buff));

        sprintf(buff, "RETR %s\r\n", filename);

        if (safesend(sockfd, buff, strlen(buff)) < 0)

        {

                close (sockfd);

                close (localsock);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                close(localsock);

                return -1;

        }

        if (strstr(buff, "150") == NULL) {

                put_log("ERROR:Unable to get valid data\n");

                close(sockfd);

                close(localsock);

                return -1;

        }

        if ((dsock = accept (localsock, (struct sockaddr *) &remote, &remote_len)) == -1) {

                put_log("ERROR:accept,%s\n", strerror(errno));

                close(sockfd);

                close(localsock);

                return -1;

        }

        close(localsock);

        if ((fd = open(filename, O_WRONLY|O_CREAT, 0644)) == -1) {

                put_log("ERROR:open,%s\n", strerror(errno));

                close (sockfd);

                close (dsock);

                return -1;

        }

        dwRead = 0;

        dw = 0;

        while (dwRead < len)

        {

                memset(buff, 0, sizeof(buff));

                dw = saferecv(dsock, buff, sizeof(buff));

                if (dw < 0)

                {

                        close (sockfd);

                        close (dsock);

                        return -1;

                }

                else if (dw == 0)

                        break;

                write(fd, buff, dw);

                dwRead += dw;

        }

        close(fd);

        memset(buff, 0, sizeof(buff));

        saferecv(dsock, buff, sizeof(buff));

        close(dsock);

        sprintf(buff, "QUIT\r\n");

        safesend(sockfd, buff, strlen(buff));

        saferecv(sockfd, buff, sizeof(buff));

        close(sockfd);

        if (dwRead == len)

                return 0;

        return -1;

}

int upload(char *ftpserver, char *username, char *password, char *filename)

{

        int          sockfd, localsock, dsock;

        int          localport;

        int          fd;

        struct sockaddr_in remote;

        int                remote_len;

        char         buff[1024];

        char         localip[256] = "10.10.17.169";

        int dwRead;

        int dw;

        if ((sockfd = connect_ftp(ftpserver, username, password)) == -1) {

                put_log("ERROR:connect_ftp\n");

                return -1;

        }

        /*get random seed*/

        srand ((double) time (NULL) * 1000000);

        /*use random number as port for ftpdata bind*/

        localport = (rand () % 20000) + 2000;

        if ((localsock = create_dataconn(sockfd, localip, localport)) == -1) {

                put_log("ERROR:connect_ftp\n");

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        sprintf(buff, "PORT %s,%d,%d\r\n", localip, localport / 256, localport % 256);

        if (safesend(sockfd, buff, strlen(buff)) < 0)

        {

                close(sockfd);

                close(localsock);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                return -1;

        }

        if (strstr(buff, "200") == NULL) {

                put_log("ERROR:Unable to get valid data\n");

                close(sockfd);

                close(localsock);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        sprintf (buff, "STOR %s\r\n", filename);

        if (safesend (sockfd, buff, strlen(buff)) < 0)

        {

                close (sockfd);

                close (localsock);

                return -1;

        }

        memset(buff, 0, sizeof(buff));

        if (saferecv(sockfd, buff, sizeof(buff)) < 0) {

                close(sockfd);

                close(localsock);

                return -1;

        }

        if (strstr(buff, "150") == NULL) {

                put_log("ERROR:Unable to get valid data\n");

                close(sockfd);

                close(localsock);

                return -1;

        }

        if ((dsock = accept (localsock, (struct sockaddr *) &remote, &remote_len)) == -1) {

                put_log("ERROR:accept,%s\n", strerror(errno));

                close(sockfd);

                close(localsock);

                return -1;

        }

        close(localsock);

        if ((fd = open(filename, O_RDONLY)) == -1) {

                put_log("ERROR:open,%s\n", strerror(errno));

                close (sockfd);

                close (dsock);

                return -1;

        }

        dwRead = 0;

        dw = 0;

        while (1)

        {

                memset(buff, 0, sizeof(buff));

                dwRead = read(fd, buff, sizeof(buff));

                if (dwRead <= 0) {

                        break;

                }

                dw = safesend(dsock, buff, dwRead);

                if (dw < 0)

                {

                        close (sockfd);

                        close (dsock);

                        return -1;

                }

                if (dwRead != sizeof(buff)) {

                        break;

                }

        }

        close(fd);

        close(dsock);

        memset(buff, 0, sizeof(buff));

        saferecv(sockfd, buff, sizeof(buff));

        while (strstr (buff, "226") == NULL)

        {

                memset(buff, 0, sizeof(buff));

                saferecv(sockfd, buff, sizeof(buff));

        }

        sprintf(buff, "QUIT\r\n");

        safesend(sockfd, buff, strlen(buff));

        saferecv(sockfd, buff, sizeof(buff));

        close(sockfd);

        return 0;

}[/code]

 

 

 

下有一个用C语言编写的简单ftp客户端源程序,里面很多功能都没有实现,主要有3个。1: 实现连接,断开,并且重新连接到ftp功能。2:实现DIR功能。 3: 实现RETR的功能。程序如下

//159.334 - Networks - 2/2004

//This example is NOT fully functional

//It may even require small changes to compile.

//Please refer to the sockets material and examples

//(compare this code with serv1.c and client.c codes)

//

//To connect use an FTP client. The port is 1221. To connect locally issue the following command:

//#ftp 127.0.0.1 1221

//

//Includes

#include

#include

#include

//Defines

#define WSVERS MAKEWORD(2,0)

WSADATA wsadata;

#define STKSIZE 16536

char sbuffer[80],rbuffer[80];//send and receive buffers

int n,bytes;//counters

SOCKET ns,ns_data;//sockets, ns is a new socket (on 1221) and ns_data is a new socket for data (1220)

struct sockaddr_in remoteaddr, remoteaddr_data;

//MAIN

main(int argc, char *argv[]) {

struct sockaddr_in localaddr;//local address structure

struct sockaddr_in local_data_addr;//local address struct for data connection

int s,s_data;//welcome socket and welcome socket for data connection

int addrlen;//address lenght variable

if (WSAStartup(WSVERS, &wsadata) != 0) {

WSACleanup();

printf("WSAStartup failed\n");

}

memset(&localaddr,0,sizeof(localaddr));//clear localaddr

memset(&local_data_addr,0,sizeof(local_data_addr));//clear local_data_addr

//SOCKETS (notice that there are two welcome sockets, one for control, one for data

s = socket(PF_INET, SOCK_STREAM, 0);

s_data = socket(PF_INET, SOCK_STREAM, 0);

if (s < 0) {

error("socket failed\n");

}

localaddr.sin_family = AF_INET;

local_data_addr.sin_family = AF_INET;

if (argc == 2) localaddr.sin_port = htons((u_short)atoi(argv[1]));

else localaddr.sin_port = htons(1221);

localaddr.sin_addr.s_addr = INADDR_ANY;

local_data_addr.sin_port = htons(1220);

local_data_addr.sin_addr.s_addr = INADDR_ANY;

//BIND (bind uses ports 1221 and 1220 by default)

if (bind(s,(struct sockaddr *)(&localaddr),sizeof(localaddr)) < 0) {

error("Bind failed!\n");

}

if (bind(s_data,(struct sockaddr *)(&local_data_addr),sizeof(local_data_addr)) < 0) {

error("Bind failed!\n");

}

//LISTEN

listen(s,5);

listen(s_data,5);

//INFINITE LOOP

while (1) {

addrlen = sizeof(remoteaddr);

//ACCEPT main connection (control connection)

ns = accept(s,(struct sockaddr *)(&remoteaddr),&addrlen);

printf("connected to %s\n",inet_ntoa(remoteaddr.sin_addr));

//Respond with welcome message, FTP client requires those

sprintf(sbuffer,"200 Welcome \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

sprintf(sbuffer,"530 Log in \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

sprintf(sbuffer,"530 Log in \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

//INFINITE LOOP

while (1) {

n = 0;

while (1) {

//RECEIVE

bytes = recv(ns, &rbuffer[n], 1, 0);

if ((bytes < 0) || (bytes == 0)) break;

if (rbuffer[n] == '\n') { /*end on LF*/

rbuffer[n] = '\0';

break;

}

if (rbuffer[n] != '\r') n++; /*ignore CR's*/

}

if ((bytes < 0) || (bytes == 0)) break;

printf("#The Server receives:# '%s' from client \n", rbuffer);

//STARTS INTERPRETATION OF THE FTP COMMANDS HERE

//Perhaps use "case" or "if/else" for this part

//It is a good idea to 'trap' any mistaken or non-implemented command returning "500 Syntax error" code

//

//USER

if (strncmp(rbuffer,"USER",4)==0) {

printf("Logging in \n");

sprintf(sbuffer,"331 Password required (anything will do really... :-) \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

}

//PASS

if (strncmp(rbuffer,"PASS",4)==0) {

printf("Typing password (anything will do... \n");

sprintf(sbuffer, "230 Public logging in ok, 无效 your email for password \r\n");

//sprintf(sbuffer, "230 Public logging in ok, 无效 your email for password \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

}

//SYST

if (strncmp(rbuffer,"SYST",4)==0) {

printf("Information about the system \n");

sprintf(sbuffer, "257 A very naive FTP system... \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

}

//PASV

if (strncmp(rbuffer,"PASV",4)==0) {

printf("Passive mode \n");

//change the IP address here if you want to connect from a remote machine

//227 has a strange format, for IP 127.0.0.1 and port 1220 this is it...)

sprintf(sbuffer, "227 Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",127,0,0,1,(1220>>8),(1220 & 0x00FF));

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

//open a new connection on port 1220

ns_data = accept(s_data,(struct sockaddr *)(&remoteaddr_data),&addrlen);

printf("connected to %s\n",inet_ntoa(remoteaddr.sin_addr));

}

//LIST

if (strncmp(rbuffer,"LIST",4)==0) {

printf("Equivalent to dir \n");

system("ls > tmp.txt");

FILE *fin=fopen("tmp.txt","r");

sprintf(sbuffer, "125 Transfering... \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

char temp_buffer[80];

while (!feof(fin)){

fgets(temp_buffer,78,fin);

sprintf(sbuffer,"%s ",temp_buffer);

send(ns_data, sbuffer, strlen(sbuffer), 0);

}

fclose(fin);

sprintf(sbuffer, "226 Transfer completed... \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

system("del tmp.txt");

//CLOSE DATA SOCKET

close(ns_data);

}

//QUIT

if (strncmp(rbuffer,"QUIT",3)==0) {

printf("quit \n");

sprintf(sbuffer, "221 Bye bye ... \r\n");

bytes = send(ns, sbuffer, strlen(sbuffer), 0);

close(ns);

printf("disconnected from %s\n",inet_ntoa(remoteaddr.sin_addr));

return;

}

}

//CLOSE CONTROL SOCKET

close(ns);

printf("disconnected from %s\n",inet_ntoa(remoteaddr.sin_addr));

}

//CLOSE WELCOME SOCKET

close(s);

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值