用了好几天的时间编写了一个ftp的客户端,使用socket通讯。服务器端使用的是vsftp,在centos下直接用yum install vsftpd安装即可。在这里我使用的是被动模式。
在编写代码时主要犯了错误:
1.在使用socket时,对于接受例如read,一定要使用其返回值,其返回值表示真正接收到的数据。而且,接受的长度为缓冲区的长度减一,其目的是为了保存'\0',在写入时,要写入接收到的字符串的长度len.
2.以下红色为自己出过错误的地方
3.要关闭服务器的防火墙服务
主要引用资料:http://www.ibm.com/developerworks/cn/linux/l-cn-socketftp/index.html
下边是代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 1024
#define server_path "config/wang" //the file you want to download
#define client_path "/opt/dcp/wang" //要下载到本地的地址
#define username "wang" //服务器的登陆名
#define code "1" //服务器的登陆密码
#define server_ip "192.168.1.126" //vsftp 服务器的ip地址
int strseparte(const char *rmt_path,char *filename,char *rmt_dir)
{
int i=0;
const char *path=rmt_path;
char *ptr1=strrchr(path,'/');
if(ptr1==NULL)
{
while(*path!='\0')
{
filename[i]=*path;
i++;
path++;
}
}
else
{
while(path
{
rmt_dir[i]=*path;
i++;
path++;
}
i=0;
ptr1++;
while(*ptr1!='\0')
{
filename[i]=*ptr1;
i++;
ptr1++;
}
}
return 0;
}
int ftp_download(const char *ip,const char *rmt_path,const char *local_path)
{
int socket_fd,date_fd;
struct sockaddr_in server_sockaddr,date_sockaddr;
char sendbuf[BUFFER_SIZE]={0};
char recvbuf[BUFFER_SIZE]={0};
int file;
int len;
int filesize;
char filename[30]={0};
char rmt_dir[50]={0};
int porttmp1,porttmp2,port;
int a1,a2,a3,a4,a5;
char str1[30],str2[30],str3[30];
if((socket_fd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(21);
server_sockaddr.sin_addr.s_addr = inet_addr(ip);
if(connect(socket_fd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) != 0)
{
perror("connect");
exit(1);
}
memset(recvbuf,0,sizeof(recvbuf));
recv(socket_fd,recvbuf,sizeof(recvbuf),0);
// printf("First recv message is:%s\n ",recvbuf);
sprintf(sendbuf,"USER %s\r\n",username);
write(socket_fd,sendbuf,strlen(sendbuf));
// printf("First send message is:%s\n",sendbuf);
read(socket_fd,recvbuf,sizeof(recvbuf));
// printf("after write USER recv message is:%s",recvbuf);
memset(sendbuf,0,sizeof(sendbuf));
sprintf(sendbuf,"PASS %s\r\n",code);
// printf("second send message is:%s\n",sendbuf);
write(socket_fd,sendbuf,strlen(sendbuf));
memset(recvbuf,0,sizeof(recvbuf));
read(socket_fd,recvbuf,sizeof(recvbuf));
// printf("after write PASS recv message is:%s",recvbuf);
memset(sendbuf,0,sizeof(sendbuf));
sprintf(sendbuf,"PASV\r\n");
write(socket_fd,sendbuf,strlen(sendbuf));
// printf("pasv send is:%s\n",sendbuf);
memset(recvbuf,0,sizeof(recvbuf));
read(socket_fd,recvbuf,sizeof(recvbuf));
// printf("after write PASV recv message is:%s",recvbuf);
sscanf(recvbuf,"%d %s %s %s (%d,%d,%d,%d,%d,%d).",&a1,str1,str2,str3,&a2,&a3,&a4,&a5,&porttmp1,&porttmp2);
// printf("porttmp1=%d,porttmp2=%d\n",porttmp1,porttmp2);
port=porttmp1*256+porttmp2;
if((date_fd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("date_fd socket");
exit(1);
}
date_sockaddr.sin_family = AF_INET;
date_sockaddr.sin_port = htons(port);
date_sockaddr.sin_addr.s_addr = inet_addr(ip);
if(connect(date_fd, (struct sockaddr *)&date_sockaddr, sizeof(struct sockaddr)) != 0)
{
perror("date_fd connect");
exit(1);
}else
printf("date_fd connect success\n");
strseparte(rmt_path,filename,rmt_dir);
if(rmt_dir!=NULL)
{
memset(sendbuf,0,sizeof(sendbuf));
sprintf(sendbuf,"CWD %s\r\n",rmt_dir);
write(socket_fd,sendbuf,strlen(sendbuf));
// printf("send cwd is:%s\n",sendbuf);
memset(recvbuf,0,sizeof(recvbuf));
read(socket_fd,recvbuf,sizeof(recvbuf));
// printf("after send cwd recv is:%s\n",recvbuf);
}
memset(sendbuf,0,sizeof(sendbuf));
sprintf(sendbuf,"SIZE %s\r\n",filename);
write(socket_fd,sendbuf,strlen(sendbuf));
// printf("send SIZE is :%s\n",sendbuf);
memset(recvbuf,0,sizeof(recvbuf));
read(socket_fd,recvbuf,sizeof(recvbuf));
// printf("after send file size recv is:%s\n",recvbuf);
sscanf(recvbuf,"%d %d",&a1,&filesize);
// printf("filesize is %d\n",filesize);
memset(sendbuf,0,sizeof(sendbuf));
sprintf(sendbuf,"RETR %s\r\n",filename);
write(socket_fd,sendbuf,strlen(sendbuf));
memset(recvbuf,0,sizeof(recvbuf));
read(socket_fd,recvbuf,sizeof(recvbuf));
// printf("1 after retr recvbuf is:%s\n",recvbuf);
memset(recvbuf,0,sizeof(recvbuf));
file=open(local_path,O_RDWR|O_CREAT|O_TRUNC,0644);
while(1)
{
if((len=read(date_fd,recvbuf,sizeof(recvbuf)-1))>0)
{
write(file,recvbuf,len);
printf("%s\n",recvbuf);
memset(recvbuf,0,sizeof(recvbuf));
}
else
{
close(file);
printf("download ok\n");
break;
}
}
close(date_fd);
memset(recvbuf,0,sizeof(recvbuf));
read(socket_fd,recvbuf,sizeof(recvbuf));
// printf("download finish:%s\n",recvbuf);
memset(sendbuf,0,sizeof(sendbuf));
sprintf(sendbuf,"QUIT\r\n");
write(socket_fd,sendbuf,strlen(sendbuf));
memset(recvbuf,0,sizeof(recvbuf));
read(socket_fd,recvbuf,sizeof(recvbuf));
// printf("after send quit:%s\n",recvbuf);
close(socket_fd);
}
int main(int argc,char *argv[])
{
ftp_download(server_ip,server_path,client_path);
return 0;
}
阅读(973) | 评论(0) | 转发(0) |