项目地址:https://github.com/gudipati/FTP-ClientServer

实现的功能

使用以下命令,能够实现对应的功能:

  • put :将名为 filename 的文件传送到服务器
  • get :从服务器下载名为 filename 的文件
  • ls:列出服务器当前路径下的所有文件
  • cd::切换服务器进入 目录
  • pwd:展示服务器当前路径
  • !ls:展示客户端当前路径下的所有文件
  • !cd :切换客户端进入 目录
  • !pwd:展示客户端当前的路径
  • quit:退出客户端 FTP 会话,返回 Unix 提示符

代码

服务器端

服务器端代码 server.cpp

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <string.h>
  8. #include <fstream>
  9. #include <unistd.h>
  10. using namespace std;
  11. int create_socket(int);
  12. int accept_conn(int);
  13. #ifdef WINDOWS
  14. #include <direct.h>
  15. #define GetCurrentDir _getcwd
  16. #else
  17. #include <unistd.h>
  18. #define GetCurrentDir getcwd
  19. #endif
  20. #define MAXLINE 4096 /*max text line length*/
  21. #define LISTENQ 8 /*maximum number of client connections*/
  22. int main (int argc, char **argv)
  23. {
  24. int listenfd, connfd, n;
  25. pid_t childpid;
  26. socklen_t clilen;
  27. char buf[MAXLINE];
  28. struct sockaddr_in cliaddr, servaddr;
  29. if (argc !=2) { //validating the input
  30. cerr<<"Usage: ./a.out <port number>"<<endl;
  31. exit(1);
  32. }
  33. //Create a socket for the soclet
  34. //If sockfd<0 there was an error in the creation of the socket
  35. if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
  36. cerr<<"Problem in creating the socket"<<endl;
  37. exit(2);
  38. }
  39. //preparation of the socket address
  40. servaddr.sin_family = AF_INET;
  41. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  42. if(atoi(argv[1])<=1024){
  43. cerr<<"Port number must be greater than 1024"<<endl;
  44. exit(2);
  45. }
  46. servaddr.sin_port = htons(atoi(argv[1]));
  47. //bind the socket
  48. bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
  49. //listen to the socket by creating a connection queue, then wait for clients
  50. listen (listenfd, LISTENQ);
  51. cout<<"Server running...waiting for connections."<<endl;
  52. for ( ; ; ) {
  53. clilen = sizeof(cliaddr);
  54. //accept a connection
  55. connfd = accept (listenfd, (struct sockaddr *) &cliaddr, &clilen);
  56. cout<<"Received request..."<<endl;
  57. if ( (childpid = fork ()) == 0 ) {//if it’s 0, it’s child process
  58. cout<<"Child created for dealing with client requests"<<endl;
  59. //close listening socket
  60. close (listenfd);
  61. int data_port=1024; //for data connection
  62. while ( (n = recv(connfd, buf, MAXLINE,0)) > 0) {
  63. cout<<"String received from client: "<<buf;
  64. char *token,*dummy;
  65. dummy=buf;
  66. token=strtok(dummy," ");
  67. if (strcmp("quit\n",buf)==0) {
  68. cout<<"The client has quit\n";
  69. }
  70. if (strcmp("ls\n",buf)==0) {
  71. FILE *in;
  72. char temp[MAXLINE],port[MAXLINE];
  73. int datasock;
  74. data_port=data_port+1;
  75. if(data_port==atoi(argv[1])){
  76. data_port=data_port+1;
  77. }
  78. sprintf(port,"%d",data_port);
  79. datasock=create_socket(data_port); //creating socket for data connection
  80. send(connfd, port,MAXLINE,0); //sending data connection port no. to client
  81. datasock=accept_conn(datasock); //accepting connection from client
  82. if(!(in = popen("ls", "r"))){
  83. cout<<"error"<<endl;
  84. }
  85. while(fgets(temp, sizeof(temp), in)!=NULL){
  86. send(datasock,"1",MAXLINE,0);
  87. send(datasock, temp, MAXLINE, 0);
  88. }
  89. send(datasock,"0",MAXLINE,0);
  90. pclose(in);
  91. //cout<<"file closed\n";
  92. }
  93. if (strcmp("pwd\n",buf)==0) {
  94. char curr_dir[MAXLINE];
  95. GetCurrentDir(curr_dir,MAXLINE-1);
  96. send(connfd, curr_dir, MAXLINE, 0);
  97. //cout<<curr_dir<<endl;
  98. }
  99. if (strcmp("cd",token)==0) {
  100. token=strtok(NULL," \n");
  101. cout<<"Path given is: "<<token<<endl;
  102. if(chdir(token)<0){
  103. send(connfd,"0",MAXLINE,0);
  104. }
  105. else{
  106. send(connfd,"1",MAXLINE,0);
  107. }
  108. }
  109. if (strcmp("put",token)==0) {
  110. char port[MAXLINE],buffer[MAXLINE],char_num_blks[MAXLINE],char_num_last_blk[MAXLINE],check[MAXLINE];
  111. int datasock,num_blks,num_last_blk,i;
  112. FILE *fp;
  113. token=strtok(NULL," \n");
  114. cout<<"Filename given is: "<<token<<endl;
  115. data_port=data_port+1;
  116. if(data_port==atoi(argv[1])){
  117. data_port=data_port+1;
  118. }
  119. sprintf(port,"%d",data_port);
  120. datasock=create_socket(data_port); //creating socket for data connection
  121. send(connfd, port,MAXLINE,0); //sending data connection port to client
  122. datasock=accept_conn(datasock); //accepting connection
  123. recv(connfd,check,MAXLINE,0);
  124. cout<<check;
  125. if(strcmp("1",check)==0){
  126. if((fp=fopen(token,"w"))==NULL)
  127. cout<<"Error in creating file\n";
  128. else
  129. {
  130. recv(connfd, char_num_blks, MAXLINE,0);
  131. num_blks=atoi(char_num_blks);
  132. for(i= 0; i < num_blks; i++) {
  133. recv(datasock, buffer, MAXLINE,0);
  134. fwrite(buffer,sizeof(char),MAXLINE,fp);
  135. //cout<<buffer<<endl;
  136. }
  137. recv(connfd, char_num_last_blk, MAXLINE,0);
  138. num_last_blk=atoi(char_num_last_blk);
  139. if (num_last_blk > 0) {
  140. recv(datasock, buffer, MAXLINE,0);
  141. fwrite(buffer,sizeof(char),num_last_blk,fp);
  142. //cout<<buffer<<endl;
  143. }
  144. fclose(fp);
  145. cout<<"File download done.\n";
  146. }
  147. }
  148. }
  149. if (strcmp("get",token)==0) {
  150. char port[MAXLINE],buffer[MAXLINE],char_num_blks[MAXLINE],char_num_last_blk[MAXLINE];
  151. int datasock,lSize,num_blks,num_last_blk,i;
  152. FILE *fp;
  153. token=strtok(NULL," \n");
  154. cout<<"Filename given is: "<<token<<endl;
  155. data_port=data_port+1;
  156. if(data_port==atoi(argv[1])){
  157. data_port=data_port+1;
  158. }
  159. sprintf(port,"%d",data_port);
  160. datasock=create_socket(data_port); //creating socket for data connection
  161. send(connfd, port,MAXLINE,0); //sending port no. to client
  162. datasock=accept_conn(datasock); //accepting connnection by client
  163. if ((fp=fopen(token,"r"))!=NULL)
  164. {
  165. //size of file
  166. send(connfd,"1",MAXLINE,0);
  167. fseek (fp , 0 , SEEK_END);
  168. lSize = ftell (fp);
  169. rewind (fp);
  170. num_blks = lSize/MAXLINE;
  171. num_last_blk = lSize%MAXLINE;
  172. sprintf(char_num_blks,"%d",num_blks);
  173. send(connfd, char_num_blks, MAXLINE, 0);
  174. //cout<<num_blks<<" "<<num_last_blk<<endl;
  175. for(i= 0; i < num_blks; i++) {
  176. fread (buffer,sizeof(char),MAXLINE,fp);
  177. send(datasock, buffer, MAXLINE, 0);
  178. //cout<<buffer<<" "<<i<<endl;
  179. }
  180. sprintf(char_num_last_blk,"%d",num_last_blk);
  181. send(connfd, char_num_last_blk, MAXLINE, 0);
  182. if (num_last_blk > 0) {
  183. fread (buffer,sizeof(char),num_last_blk,fp);
  184. send(datasock, buffer, MAXLINE, 0);
  185. //cout<<buffer<<endl;
  186. }
  187. fclose(fp);
  188. cout<<"File upload done.\n";
  189. }
  190. else{
  191. send(connfd,"0",MAXLINE,0);
  192. }
  193. }
  194. }
  195. if (n < 0)
  196. cout<<"Read error"<<endl;
  197. exit(0);
  198. }
  199. //close socket of the server
  200. close(connfd);
  201. }
  202. }
  203. int create_socket(int port)
  204. {
  205. int listenfd;
  206. struct sockaddr_in dataservaddr;
  207. //Create a socket for the soclet
  208. //If sockfd<0 there was an error in the creation of the socket
  209. if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
  210. cerr<<"Problem in creating the data socket"<<endl;
  211. exit(2);
  212. }
  213. //preparation of the socket address
  214. dataservaddr.sin_family = AF_INET;
  215. dataservaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  216. dataservaddr.sin_port = htons(port);
  217. if ((bind (listenfd, (struct sockaddr *) &dataservaddr, sizeof(dataservaddr))) <0) {
  218. cerr<<"Problem in binding the data socket"<<endl;
  219. exit(2);
  220. }
  221. //listen to the socket by creating a connection queue, then wait for clients
  222. listen (listenfd, 1);
  223. return(listenfd);
  224. }
  225. int accept_conn(int sock)
  226. {
  227. int dataconnfd;
  228. socklen_t dataclilen;
  229. struct sockaddr_in datacliaddr;
  230. dataclilen = sizeof(datacliaddr);
  231. //accept a connection
  232. if ((dataconnfd = accept (sock, (struct sockaddr *) &datacliaddr, &dataclilen)) <0) {
  233. cerr<<"Problem in accepting the data socket"<<endl;
  234. exit(2);
  235. }
  236. return(dataconnfd);
  237. }

客户端

客户端代码 client.cpp

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <fstream>
  8. #include <string.h>
  9. #include <arpa/inet.h>
  10. using namespace std;
  11. int create_socket(int,char *);
  12. #ifdef WINDOWS
  13. #include <direct.h>
  14. #define GetCurrentDir _getcwd
  15. #else
  16. #include <unistd.h>
  17. #define GetCurrentDir getcwd
  18. #endif
  19. #define MAXLINE 4096 /*max text line length*/
  20. int
  21. main(int argc, char **argv)
  22. {
  23. int sockfd;
  24. struct sockaddr_in servaddr;
  25. char sendline[MAXLINE], recvline[MAXLINE];
  26. //basic check of the arguments
  27. //additional checks can be inserted
  28. if (argc !=3) {
  29. cerr<<"Usage: ./a.out <IP address of the server> <port number>"<<endl;
  30. exit(1);
  31. }
  32. //Create a socket for the client
  33. //If sockfd<0 there was an error in the creation of the socket
  34. if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
  35. cerr<<"Problem in creating the socket"<<endl;
  36. exit(2);
  37. }
  38. //Creation of the socket
  39. memset(&servaddr, 0, sizeof(servaddr));
  40. servaddr.sin_family = AF_INET;
  41. servaddr.sin_addr.s_addr= inet_addr(argv[1]);
  42. servaddr.sin_port = htons(atoi(argv[2])); //convert to big-endian order
  43. //Connection of the client to the socket
  44. if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) {
  45. cerr<<"Problem in connecting to the server"<<endl;
  46. exit(3);
  47. }
  48. cout<<"ftp>";
  49. while (fgets(sendline, MAXLINE, stdin) != NULL) {
  50. send(sockfd, sendline, MAXLINE, 0);
  51. char *token,*dummy;
  52. dummy=sendline;
  53. token=strtok(dummy," ");
  54. if (strcmp("quit\n",sendline)==0) {
  55. //close(sockfd);
  56. return 0;
  57. }
  58. else if (strcmp("ls\n",sendline)==0) {
  59. char buff[MAXLINE],check[MAXLINE]="1",port[MAXLINE];
  60. int data_port,datasock;
  61. recv(sockfd, port, MAXLINE,0); //reciening data connection port
  62. data_port=atoi(port);
  63. datasock=create_socket(data_port,argv[1]);
  64. while(strcmp("1",check)==0){ //to indicate that more blocks are coming
  65. recv(datasock,check,MAXLINE,0);
  66. if(strcmp("0",check)==0) //no more blocks of data
  67. break;
  68. recv(datasock, buff, MAXLINE,0);
  69. cout<<buff;
  70. }
  71. }
  72. else if (strcmp("!ls\n",sendline)==0) {
  73. system("ls");
  74. cout<<"\n";
  75. }
  76. else if (strcmp("pwd\n",sendline)==0) {
  77. char curr_dir[MAXLINE];
  78. recv(sockfd, curr_dir, MAXLINE,0);
  79. cout<<curr_dir<<endl;
  80. }
  81. else if (strcmp("!pwd\n",sendline)==0) {
  82. system("pwd");
  83. }
  84. else if (strcmp("cd",token)==0) {
  85. char check[MAXLINE];
  86. token=strtok(NULL," \n");
  87. cout<<"Path given is: "<<token<<endl;
  88. recv(sockfd,check,MAXLINE,0);
  89. if(strcmp("0",check)==0){
  90. cerr<<"Directory doesn't exist. Check Path"<<endl;
  91. }
  92. }
  93. else if (strcmp("!cd",token)==0) {
  94. token=strtok(NULL," \n");
  95. cout<<"Path given is: "<<token<<endl;
  96. if(chdir(token)<0){
  97. cerr<<"Directory doesn't exist. Check path"<<endl;
  98. }
  99. }
  100. else if (strcmp("put",token)==0) {
  101. char port[MAXLINE], buffer[MAXLINE],char_num_blks[MAXLINE],char_num_last_blk[MAXLINE];
  102. int data_port,datasock,lSize,num_blks,num_last_blk,i;
  103. FILE *fp;
  104. recv(sockfd, port, MAXLINE,0); //receiving the data port
  105. data_port=atoi(port);
  106. datasock=create_socket(data_port,argv[1]);
  107. token=strtok(NULL," \n");
  108. if ((fp=fopen(token,"r"))!=NULL)
  109. {
  110. //size of file
  111. send(sockfd,"1",MAXLINE,0);
  112. fseek (fp , 0 , SEEK_END);
  113. lSize = ftell (fp);
  114. rewind (fp);
  115. num_blks = lSize/MAXLINE;
  116. num_last_blk = lSize%MAXLINE;
  117. sprintf(char_num_blks,"%d",num_blks);
  118. send(sockfd, char_num_blks, MAXLINE, 0);
  119. //cout<<num_blks<<" "<<num_last_blk<<endl;
  120. for(i= 0; i < num_blks; i++) {
  121. fread (buffer,sizeof(char),MAXLINE,fp);
  122. send(datasock, buffer, MAXLINE, 0);
  123. //cout<<buffer<<" "<<i<<endl;
  124. }
  125. sprintf(char_num_last_blk,"%d",num_last_blk);
  126. send(sockfd, char_num_last_blk, MAXLINE, 0);
  127. if (num_last_blk > 0) {
  128. fread (buffer,sizeof(char),num_last_blk,fp);
  129. send(datasock, buffer, MAXLINE, 0);
  130. //cout<<buffer<<endl;
  131. }
  132. fclose(fp);
  133. cout<<"File upload done.\n";
  134. }
  135. else{
  136. send(sockfd,"0",MAXLINE,0);
  137. cerr<<"Error in opening file. Check filename\nUsage: put filename"<<endl;
  138. }
  139. }
  140. else if (strcmp("get",token)==0) {
  141. char port[MAXLINE], buffer[MAXLINE],char_num_blks[MAXLINE],char_num_last_blk[MAXLINE],message[MAXLINE];
  142. int data_port,datasock,lSize,num_blks,num_last_blk,i;
  143. FILE *fp;
  144. recv(sockfd, port, MAXLINE,0);
  145. data_port=atoi(port);
  146. datasock=create_socket(data_port,argv[1]);
  147. token=strtok(NULL," \n");
  148. recv(sockfd,message,MAXLINE,0);
  149. if(strcmp("1",message)==0){
  150. if((fp=fopen(token,"w"))==NULL)
  151. cout<<"Error in creating file\n";
  152. else
  153. {
  154. recv(sockfd, char_num_blks, MAXLINE,0);
  155. num_blks=atoi(char_num_blks);
  156. for(i= 0; i < num_blks; i++) {
  157. recv(datasock, buffer, MAXLINE,0);
  158. fwrite(buffer,sizeof(char),MAXLINE,fp);
  159. //cout<<buffer<<endl;
  160. }
  161. recv(sockfd, char_num_last_blk, MAXLINE,0);
  162. num_last_blk=atoi(char_num_last_blk);
  163. if (num_last_blk > 0) {
  164. recv(datasock, buffer, MAXLINE,0);
  165. fwrite(buffer,sizeof(char),num_last_blk,fp);
  166. //cout<<buffer<<endl;
  167. }
  168. fclose(fp);
  169. cout<<"File download done."<<endl;
  170. }
  171. }
  172. else{
  173. cerr<<"Error in opening file. Check filename\nUsage: put filename"<<endl;
  174. }
  175. }
  176. else{
  177. cerr<<"Error in command. Check Command"<<endl;
  178. }
  179. cout<<"ftp>";
  180. }
  181. exit(0);
  182. }
  183. int create_socket(int port,char *addr)
  184. {
  185. int sockfd;
  186. struct sockaddr_in servaddr;
  187. //Create a socket for the client
  188. //If sockfd<0 there was an error in the creation of the socket
  189. if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
  190. cerr<<"Problem in creating the socket"<<endl;
  191. exit(2);
  192. }
  193. //Creation of the socket
  194. memset(&servaddr, 0, sizeof(servaddr));
  195. servaddr.sin_family = AF_INET;
  196. servaddr.sin_addr.s_addr= inet_addr(addr);
  197. servaddr.sin_port = htons(port); //convert to big-endian order
  198. //Connection of the client to the socket
  199. if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) {
  200. cerr<<"Problem in creating data channel"<<endl;
  201. exit(3);
  202. }
  203. return(sockfd);
  204. }