FTP客戶端實現斷點續傳
阿新 • • 發佈:2019-02-02
FTP客戶端是自己做的的第一個C專案,大二暑假做的。現在拿出來看看,當時只是初學者,暑假在學校一個人做了1個多星期。當代碼成功執行時,瞬間感到C的強大與程式設計的樂趣。不懂的朋友可以問我。
connect.c
#include <stdio.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #define SERV_IP "127.0.0.1" #define SERV_PORT 21 char read_buf[1024]; char send_buf[1024]; int control_sock,n; int main(int argc,char *argv[]) { /* 初始化socket */ struct sockaddr_in servaddr; bzero(read_buf,sizeof(read_buf)); bzero(send_buf,sizeof(send_buf)); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton(AF_INET,SERV_IP,&servaddr.sin_addr); servaddr.sin_port = htons(SERV_PORT); control_sock = socket(AF_INET, SOCK_STREAM, 0); /* 連線到伺服器端 */ connect(control_sock, (struct sockaddr *)&servaddr, sizeof(servaddr)); /* 客戶端接收伺服器端的一些歡迎資訊 */ n=read(control_sock, read_buf, sizeof(read_buf)); if(n<0) { perror("read error"); exit(1); } printf("From server %s\n",read_buf); login(); }
login.c
#include <stdio.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #define SERV_IP "127.0.0.1" #define SERV_PORT 21 char read_buf[1024]; char send_buf[1024]; int control_sock,n; void login() { /* 命令 ”USER username\r\n” */ strcpy(send_buf,"USER sunmeng\r\n"); /*客戶端傳送使用者名稱到伺服器端 */ n=write(control_sock,send_buf,strlen(send_buf)); if(n<0) { perror("write username error"); exit(1); } /* 客戶端接收伺服器的響應碼和資訊,正常為 ”331 User name okay, need password.” */ bzero(send_buf,sizeof(send_buf)); n=read(control_sock,send_buf,sizeof(send_buf)); if(n<0) { perror("read error"); exit(1); } printf("From server %s\n",send_buf); bzero(read_buf,sizeof(read_buf)); strncpy(read_buf,send_buf,3); // printf("%s",read_buf); if(strcmp(read_buf,"331")==0) { /* 命令 ”PASS password\r\n” */ bzero(read_buf,sizeof(read_buf)); bzero(send_buf,sizeof(send_buf)); strcpy(send_buf,"PASS smeng1114\r\n"); /* 客戶端傳送密碼到伺服器端 */ n=write(control_sock,send_buf,strlen(send_buf)); //printf("%d",strlen(send_buf)); if(n<0) { perror("write username error"); exit(1); } /* 客戶端接收伺服器的響應碼和資訊,正常為 ”230 User logged in, proceed.” */ bzero(send_buf,sizeof(send_buf)); n=read(control_sock,send_buf,sizeof(send_buf)); if(n<0) { perror("read error"); exit(1); } printf("From server %s\n",send_buf); } mode(); }
mode.c
#include <stdio.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #define SERV_IP "127.0.0.1" #define SERV_PORT 21 char read_buf[1024]; char send_buf[1024]; char *p,*s; int control_sock,data_sock,n,p1,p2; void mode() { /* 命令 ”PASV\r\n” */ bzero(send_buf,sizeof(send_buf)); strcpy(send_buf,"PASV\r\n"); /* 客戶端告訴伺服器用被動模式 */ n=write(control_sock,send_buf,strlen(send_buf)); //printf("%s\n",send_buf); if(n<0) { perror("write mode error"); exit(1); } /*客戶端接收伺服器的響應碼和新開的埠號, * 正常為 ”227 Entering passive mode (<h1,h2,h3,h4,p1,p2>)” */ n=read(control_sock, read_buf, sizeof(read_buf)); if(n<0) { perror("read mode error"); exit(1); } printf("From server %s\n",read_buf); p=strtok(read_buf,","); //printf("%s\n",p); p=strtok(NULL,","); p=strtok(NULL,","); p=strtok(NULL,","); p=strtok(NULL,","); //printf("%s\n",p); s=strtok(NULL,")"); //printf("%s\n",s); /*字串轉換成整數*/ p1=atoi(p); p2=atoi(s); data_sock=p1*256+p2; //printf("%d\n",data_sock); down(); }
down.c
#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SERV_IP "127.0.0.1"
#define SERV_PORT 21
char read_buf[100];
char send_buf[100];
int control_sock,data_sock,n;
void down()
{
/* 連線伺服器新開的資料埠 */
struct sockaddr_in servaddr;
bzero(read_buf,sizeof(read_buf));
bzero(send_buf,sizeof(send_buf));
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET,SERV_IP,&servaddr.sin_addr);
servaddr.sin_port = htons(data_sock);
data_sock = socket(AF_INET, SOCK_STREAM, 0);
connect(data_sock,(struct sockaddr *)&servaddr, sizeof(servaddr));
// printf("%d\n",data_sock);
/* 命令 ”CWD dirname\r\n” */
strcpy(send_buf,"CWD /home/sunmeng/zhongbei/FTP\r\n");
/* 客戶端傳送命令改變工作目錄 */
n=write(control_sock, send_buf, strlen(send_buf));
if(n<0)
{
perror("write error");
exit(1);
}
/* 客戶端接收伺服器的響應碼和資訊,正常為 ”250 Command okay.” */
n=read(control_sock, read_buf, sizeof(read_buf));
if(n<0)
{
perror("read error");
exit(1);
}
printf("%s\n",read_buf);
/* 命令 ”SIZE filename\r\n” */
bzero(read_buf,sizeof(read_buf));
bzero(send_buf,sizeof(send_buf));
strcpy(send_buf,"SIZE ge.mp3\r\n");
/* 客戶端傳送命令從伺服器端得到下載檔案的大小 */
n=write(control_sock, send_buf, strlen(send_buf));
if(n<0)
{
perror("write error");
exit(1);
}
/* 客戶端接收伺服器的響應碼和資訊,正常為 ”213 <size>” */
n=read(control_sock, read_buf, sizeof(read_buf));
if(n<0)
{
perror("read error");
exit(1);
}
printf("%s\n",read_buf);
/* 命令 ”RETR filename\r\n” */
bzero(read_buf,sizeof(read_buf));
bzero(send_buf,sizeof(send_buf));
strcpy(send_buf,"RETR ge.mp3\r\n");
/* 客戶端傳送命令從伺服器端下載檔案 */
n=write(control_sock, send_buf, strlen(send_buf));
if(n<0)
{
perror("write error");
exit(1);
}
/* 客戶端接收伺服器的響應碼和資訊,正常為 ”150 Opening data connection.” */
//printf("%d\n",data_sock);
/*read阻塞 只有匿名使用者才能下載*/
n=read(control_sock, read_buf, sizeof(read_buf));
if(n<0)
{
perror("read error");
exit(1);
}
printf("%s\n",read_buf);
/* 客戶端建立檔案 */
int file=1;;
n = open("gequ.mp3", O_RDWR|O_CREAT, 0666);
while(file>0) {
/* 客戶端通過資料連線 從伺服器接收檔案內容 */
bzero(read_buf,sizeof(read_buf));
file =read(data_sock, read_buf, sizeof(read_buf));
if(file<0)
{
perror("create file error");
exit(1);
}
/* 客戶端寫檔案 */
file = write(n, read_buf, strlen(read_buf));
if(file<0)
{
perror("write error");
exit(1);
}
}
/* 客戶端關閉檔案 */
close(n);
}