项目地址:https://github.com/gudipati/FTP-ClientServer
实现的功能
使用以下命令,能够实现对应的功能:
- put
:将名为 filename 的文件传送到服务器 - get
:从服务器下载名为 filename 的文件 - ls:列出服务器当前路径下的所有文件
- cd:
:切换服务器进入 目录 - pwd:展示服务器当前路径
- !ls:展示客户端当前路径下的所有文件
- !cd
:切换客户端进入 目录 - !pwd:展示客户端当前的路径
- quit:退出客户端 FTP 会话,返回 Unix 提示符
代码
服务器端
服务器端代码 server.cpp
#include <iostream>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <fstream>#include <unistd.h>using namespace std;int create_socket(int);int accept_conn(int);#ifdef WINDOWS#include <direct.h>#define GetCurrentDir _getcwd#else#include <unistd.h>#define GetCurrentDir getcwd#endif#define MAXLINE 4096 /*max text line length*/#define LISTENQ 8 /*maximum number of client connections*/int main (int argc, char **argv){int listenfd, connfd, n;pid_t childpid;socklen_t clilen;char buf[MAXLINE];struct sockaddr_in cliaddr, servaddr;if (argc !=2) { //validating the inputcerr<<"Usage: ./a.out <port number>"<<endl;exit(1);}//Create a socket for the soclet//If sockfd<0 there was an error in the creation of the socketif ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {cerr<<"Problem in creating the socket"<<endl;exit(2);}//preparation of the socket addressservaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);if(atoi(argv[1])<=1024){cerr<<"Port number must be greater than 1024"<<endl;exit(2);}servaddr.sin_port = htons(atoi(argv[1]));//bind the socketbind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));//listen to the socket by creating a connection queue, then wait for clientslisten (listenfd, LISTENQ);cout<<"Server running...waiting for connections."<<endl;for ( ; ; ) {clilen = sizeof(cliaddr);//accept a connectionconnfd = accept (listenfd, (struct sockaddr *) &cliaddr, &clilen);cout<<"Received request..."<<endl;if ( (childpid = fork ()) == 0 ) {//if it’s 0, it’s child processcout<<"Child created for dealing with client requests"<<endl;//close listening socketclose (listenfd);int data_port=1024; //for data connectionwhile ( (n = recv(connfd, buf, MAXLINE,0)) > 0) {cout<<"String received from client: "<<buf;char *token,*dummy;dummy=buf;token=strtok(dummy," ");if (strcmp("quit\n",buf)==0) {cout<<"The client has quit\n";}if (strcmp("ls\n",buf)==0) {FILE *in;char temp[MAXLINE],port[MAXLINE];int datasock;data_port=data_port+1;if(data_port==atoi(argv[1])){data_port=data_port+1;}sprintf(port,"%d",data_port);datasock=create_socket(data_port); //creating socket for data connectionsend(connfd, port,MAXLINE,0); //sending data connection port no. to clientdatasock=accept_conn(datasock); //accepting connection from clientif(!(in = popen("ls", "r"))){cout<<"error"<<endl;}while(fgets(temp, sizeof(temp), in)!=NULL){send(datasock,"1",MAXLINE,0);send(datasock, temp, MAXLINE, 0);}send(datasock,"0",MAXLINE,0);pclose(in);//cout<<"file closed\n";}if (strcmp("pwd\n",buf)==0) {char curr_dir[MAXLINE];GetCurrentDir(curr_dir,MAXLINE-1);send(connfd, curr_dir, MAXLINE, 0);//cout<<curr_dir<<endl;}if (strcmp("cd",token)==0) {token=strtok(NULL," \n");cout<<"Path given is: "<<token<<endl;if(chdir(token)<0){send(connfd,"0",MAXLINE,0);}else{send(connfd,"1",MAXLINE,0);}}if (strcmp("put",token)==0) {char port[MAXLINE],buffer[MAXLINE],char_num_blks[MAXLINE],char_num_last_blk[MAXLINE],check[MAXLINE];int datasock,num_blks,num_last_blk,i;FILE *fp;token=strtok(NULL," \n");cout<<"Filename given is: "<<token<<endl;data_port=data_port+1;if(data_port==atoi(argv[1])){data_port=data_port+1;}sprintf(port,"%d",data_port);datasock=create_socket(data_port); //creating socket for data connectionsend(connfd, port,MAXLINE,0); //sending data connection port to clientdatasock=accept_conn(datasock); //accepting connectionrecv(connfd,check,MAXLINE,0);cout<<check;if(strcmp("1",check)==0){if((fp=fopen(token,"w"))==NULL)cout<<"Error in creating file\n";else{recv(connfd, char_num_blks, MAXLINE,0);num_blks=atoi(char_num_blks);for(i= 0; i < num_blks; i++) {recv(datasock, buffer, MAXLINE,0);fwrite(buffer,sizeof(char),MAXLINE,fp);//cout<<buffer<<endl;}recv(connfd, char_num_last_blk, MAXLINE,0);num_last_blk=atoi(char_num_last_blk);if (num_last_blk > 0) {recv(datasock, buffer, MAXLINE,0);fwrite(buffer,sizeof(char),num_last_blk,fp);//cout<<buffer<<endl;}fclose(fp);cout<<"File download done.\n";}}}if (strcmp("get",token)==0) {char port[MAXLINE],buffer[MAXLINE],char_num_blks[MAXLINE],char_num_last_blk[MAXLINE];int datasock,lSize,num_blks,num_last_blk,i;FILE *fp;token=strtok(NULL," \n");cout<<"Filename given is: "<<token<<endl;data_port=data_port+1;if(data_port==atoi(argv[1])){data_port=data_port+1;}sprintf(port,"%d",data_port);datasock=create_socket(data_port); //creating socket for data connectionsend(connfd, port,MAXLINE,0); //sending port no. to clientdatasock=accept_conn(datasock); //accepting connnection by clientif ((fp=fopen(token,"r"))!=NULL){//size of filesend(connfd,"1",MAXLINE,0);fseek (fp , 0 , SEEK_END);lSize = ftell (fp);rewind (fp);num_blks = lSize/MAXLINE;num_last_blk = lSize%MAXLINE;sprintf(char_num_blks,"%d",num_blks);send(connfd, char_num_blks, MAXLINE, 0);//cout<<num_blks<<" "<<num_last_blk<<endl;for(i= 0; i < num_blks; i++) {fread (buffer,sizeof(char),MAXLINE,fp);send(datasock, buffer, MAXLINE, 0);//cout<<buffer<<" "<<i<<endl;}sprintf(char_num_last_blk,"%d",num_last_blk);send(connfd, char_num_last_blk, MAXLINE, 0);if (num_last_blk > 0) {fread (buffer,sizeof(char),num_last_blk,fp);send(datasock, buffer, MAXLINE, 0);//cout<<buffer<<endl;}fclose(fp);cout<<"File upload done.\n";}else{send(connfd,"0",MAXLINE,0);}}}if (n < 0)cout<<"Read error"<<endl;exit(0);}//close socket of the serverclose(connfd);}}int create_socket(int port){int listenfd;struct sockaddr_in dataservaddr;//Create a socket for the soclet//If sockfd<0 there was an error in the creation of the socketif ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {cerr<<"Problem in creating the data socket"<<endl;exit(2);}//preparation of the socket addressdataservaddr.sin_family = AF_INET;dataservaddr.sin_addr.s_addr = htonl(INADDR_ANY);dataservaddr.sin_port = htons(port);if ((bind (listenfd, (struct sockaddr *) &dataservaddr, sizeof(dataservaddr))) <0) {cerr<<"Problem in binding the data socket"<<endl;exit(2);}//listen to the socket by creating a connection queue, then wait for clientslisten (listenfd, 1);return(listenfd);}int accept_conn(int sock){int dataconnfd;socklen_t dataclilen;struct sockaddr_in datacliaddr;dataclilen = sizeof(datacliaddr);//accept a connectionif ((dataconnfd = accept (sock, (struct sockaddr *) &datacliaddr, &dataclilen)) <0) {cerr<<"Problem in accepting the data socket"<<endl;exit(2);}return(dataconnfd);}
客户端
客户端代码 client.cpp
#include <iostream>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <fstream>#include <string.h>#include <arpa/inet.h>using namespace std;int create_socket(int,char *);#ifdef WINDOWS#include <direct.h>#define GetCurrentDir _getcwd#else#include <unistd.h>#define GetCurrentDir getcwd#endif#define MAXLINE 4096 /*max text line length*/intmain(int argc, char **argv){int sockfd;struct sockaddr_in servaddr;char sendline[MAXLINE], recvline[MAXLINE];//basic check of the arguments//additional checks can be insertedif (argc !=3) {cerr<<"Usage: ./a.out <IP address of the server> <port number>"<<endl;exit(1);}//Create a socket for the client//If sockfd<0 there was an error in the creation of the socketif ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {cerr<<"Problem in creating the socket"<<endl;exit(2);}//Creation of the socketmemset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr= inet_addr(argv[1]);servaddr.sin_port = htons(atoi(argv[2])); //convert to big-endian order//Connection of the client to the socketif (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) {cerr<<"Problem in connecting to the server"<<endl;exit(3);}cout<<"ftp>";while (fgets(sendline, MAXLINE, stdin) != NULL) {send(sockfd, sendline, MAXLINE, 0);char *token,*dummy;dummy=sendline;token=strtok(dummy," ");if (strcmp("quit\n",sendline)==0) {//close(sockfd);return 0;}else if (strcmp("ls\n",sendline)==0) {char buff[MAXLINE],check[MAXLINE]="1",port[MAXLINE];int data_port,datasock;recv(sockfd, port, MAXLINE,0); //reciening data connection portdata_port=atoi(port);datasock=create_socket(data_port,argv[1]);while(strcmp("1",check)==0){ //to indicate that more blocks are comingrecv(datasock,check,MAXLINE,0);if(strcmp("0",check)==0) //no more blocks of databreak;recv(datasock, buff, MAXLINE,0);cout<<buff;}}else if (strcmp("!ls\n",sendline)==0) {system("ls");cout<<"\n";}else if (strcmp("pwd\n",sendline)==0) {char curr_dir[MAXLINE];recv(sockfd, curr_dir, MAXLINE,0);cout<<curr_dir<<endl;}else if (strcmp("!pwd\n",sendline)==0) {system("pwd");}else if (strcmp("cd",token)==0) {char check[MAXLINE];token=strtok(NULL," \n");cout<<"Path given is: "<<token<<endl;recv(sockfd,check,MAXLINE,0);if(strcmp("0",check)==0){cerr<<"Directory doesn't exist. Check Path"<<endl;}}else if (strcmp("!cd",token)==0) {token=strtok(NULL," \n");cout<<"Path given is: "<<token<<endl;if(chdir(token)<0){cerr<<"Directory doesn't exist. Check path"<<endl;}}else if (strcmp("put",token)==0) {char port[MAXLINE], buffer[MAXLINE],char_num_blks[MAXLINE],char_num_last_blk[MAXLINE];int data_port,datasock,lSize,num_blks,num_last_blk,i;FILE *fp;recv(sockfd, port, MAXLINE,0); //receiving the data portdata_port=atoi(port);datasock=create_socket(data_port,argv[1]);token=strtok(NULL," \n");if ((fp=fopen(token,"r"))!=NULL){//size of filesend(sockfd,"1",MAXLINE,0);fseek (fp , 0 , SEEK_END);lSize = ftell (fp);rewind (fp);num_blks = lSize/MAXLINE;num_last_blk = lSize%MAXLINE;sprintf(char_num_blks,"%d",num_blks);send(sockfd, char_num_blks, MAXLINE, 0);//cout<<num_blks<<" "<<num_last_blk<<endl;for(i= 0; i < num_blks; i++) {fread (buffer,sizeof(char),MAXLINE,fp);send(datasock, buffer, MAXLINE, 0);//cout<<buffer<<" "<<i<<endl;}sprintf(char_num_last_blk,"%d",num_last_blk);send(sockfd, char_num_last_blk, MAXLINE, 0);if (num_last_blk > 0) {fread (buffer,sizeof(char),num_last_blk,fp);send(datasock, buffer, MAXLINE, 0);//cout<<buffer<<endl;}fclose(fp);cout<<"File upload done.\n";}else{send(sockfd,"0",MAXLINE,0);cerr<<"Error in opening file. Check filename\nUsage: put filename"<<endl;}}else if (strcmp("get",token)==0) {char port[MAXLINE], buffer[MAXLINE],char_num_blks[MAXLINE],char_num_last_blk[MAXLINE],message[MAXLINE];int data_port,datasock,lSize,num_blks,num_last_blk,i;FILE *fp;recv(sockfd, port, MAXLINE,0);data_port=atoi(port);datasock=create_socket(data_port,argv[1]);token=strtok(NULL," \n");recv(sockfd,message,MAXLINE,0);if(strcmp("1",message)==0){if((fp=fopen(token,"w"))==NULL)cout<<"Error in creating file\n";else{recv(sockfd, char_num_blks, MAXLINE,0);num_blks=atoi(char_num_blks);for(i= 0; i < num_blks; i++) {recv(datasock, buffer, MAXLINE,0);fwrite(buffer,sizeof(char),MAXLINE,fp);//cout<<buffer<<endl;}recv(sockfd, char_num_last_blk, MAXLINE,0);num_last_blk=atoi(char_num_last_blk);if (num_last_blk > 0) {recv(datasock, buffer, MAXLINE,0);fwrite(buffer,sizeof(char),num_last_blk,fp);//cout<<buffer<<endl;}fclose(fp);cout<<"File download done."<<endl;}}else{cerr<<"Error in opening file. Check filename\nUsage: put filename"<<endl;}}else{cerr<<"Error in command. Check Command"<<endl;}cout<<"ftp>";}exit(0);}int create_socket(int port,char *addr){int sockfd;struct sockaddr_in servaddr;//Create a socket for the client//If sockfd<0 there was an error in the creation of the socketif ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {cerr<<"Problem in creating the socket"<<endl;exit(2);}//Creation of the socketmemset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr= inet_addr(addr);servaddr.sin_port = htons(port); //convert to big-endian order//Connection of the client to the socketif (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) {cerr<<"Problem in creating data channel"<<endl;exit(3);}return(sockfd);}
