1. 程式人生 > >FTP客戶端實現斷點續傳

FTP客戶端實現斷點續傳

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);

}