程序使用
1.运行服务端 ./ftp_server 出现ftp>
输入 get filename1.txt (filename1.txt为接收文件的名字)
2.运行客户端,如果是本机 ./fpt 127.0.0.1,出现ftp>
输入 put filename2.txt (filename2.txt)为要发送的文件。
- void get_cmd(char **p)
- {
- fgets(*p,100,stdin);
- }
- /*将带有空格的字符串s进行解析,存放到cmd字符串数组中*/
- int split_string(char *s,char _cmd[][100])
- {
- char *p = s;
- int i = 0;
- int j = 0;
- while(*p != '\n')
- {
- if(*p == ' ')
- {
- _cmd[i][j]='\0';
- i++;
- j = 0;
- p++;
- /*处理多个空格的情况*/
- while(*p == ' ')
- {
- p++;
- }
- }
- else
- {
- _cmd[i][j] = *p;
- p++;
- j++;
- }
- }
- return i+1;
- }
2.服务端ftp_server.c
- /*
- UDP 传输方式实现FTP,服务器段
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <errno.h>
- #include <sys/types.h>
- #include "cmd.h"
- int port = 8888;
- int sockfd;
- int bind_ret; /*绑定的返回值*/
- //void get_cmd(char **p);/*从控制台获取命令*/
- //int split_string(char *s,char _cmd[][100]); /*解析命令*/
- struct sockaddr_in adr_inet;/*服务器端地址信息*/
- void bind_ip();/*绑定服务器地址信息*/
- void get_file(char *_filename);/*接受文件*/
- int main()
- {
- char *s; /*从控制台获得的命令*/
- char (*cmd)[100];/*分割后的命令*/
- int len;/*参数个数*/
- s = (char *)malloc(sizeof(char)*100);
- cmd = (char (*)[])malloc(sizeof(s)*10);
-
- bind_ip();
- printf("ftp>");
- get_cmd(&s);
- split_string(s,cmd);
- while(strcmp(cmd[0],"quit") != 0)
- {
- if(strcmp(cmd[0],"get") == 0)
- {
- char filename[100];
- strcpy(filename,cmd[1]);
- if(!fork())
- {
- get_file(filename);
- exit(0);
- }
-
- }
- get_cmd(&s);
- len = split_string(s,cmd);
- }
-
- close(sockfd);
- exit(0);
- }
- /*绑定服务器地址信息*/
- void bind_ip()
- {
- /*建立IP地址*/
- adr_inet.sin_family = AF_INET;
- adr_inet.sin_port = htons(port);
- adr_inet.sin_addr.s_addr = htonl(INADDR_ANY);
- bzero(&(adr_inet.sin_zero),8);
- /*建立socket*/
- sockfd = socket(AF_INET,SOCK_DGRAM,0);
- if(sockfd == -1)
- {
- perror("socket error!");
- exit(1);
- }
- /*绑定socket*/
- bind_ret = bind(sockfd,(struct sockaddr *)&adr_inet,sizeof(adr_inet));
-
- if(bind_ret == -1)
- {
- perror("bind error!");
- exit(1);
- }
-
- }
- /*接受文件*/
- void get_file(char *_filename)
- {
- int len;
- char buf[256];
- struct sockaddr_in adr_clnt;/*用来保存客户端地址信息*/
- len = sizeof(adr_clnt);
-
- /*创建一个文件,用来保存传送过来的文件*/
- FILE *fp;
- fp = fopen(_filename,"w+");
- if(fp == NULL)
- {
- perror("create file error!");
- exit(1);
- }
- printf("Waiting client to download!\n");
- while(1)
- {
- /*接受传来的信息*/
- bind_ret = recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&adr_clnt,&len);
- if(bind_ret < 0)
- {
- perror("recvfrom error!");
- exit(1);
- }
- buf[bind_ret] = '\0';
- if(strncmp(buf,"stop",4) != 0)
- {
- //printf("receive :%s\n",buf);
- fputs(buf,fp);
- }
-
- if(strncmp(buf,"stop",4) == 0)
- {
- printf("Finished!\n");
- break;
- }
- }
- close(fp);
- printf("ftp>");
- }
3.客户端ftp.c
- /*
- UDP 传输方式实现FTP,客户段
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <malloc.h>
- #include "cmd.h"
- int port = 8888;
- int sockfd;/*套接字描述符*/
- struct sockaddr_in adr_srvr;/*服务器地址信息*/
- //void get_cmd(char **p);/*从控制台获取命令*/
- int connect_to_server(char * ip);/*连接服务器*/
- //int split_string(char *s,char _cmd[][100]); /*解析命令*/
- void send_file(char *filename);/*发送文件*/
- int main(int argc,char **argv)
- {
-
- connect_to_server(argv[1]);
- //connect_to_server("127.0.0.1");
- char *s; /*从控制台获得的命令*/
- char (*cmd)[100];/*分割后的命令*/
- int len;/*输入的参数个数*/
- s = (char *)malloc(sizeof(char)*100);
- cmd = (char (*)[])malloc(sizeof(s)*10);
- printf("ftp>");
- /*注意不能用get_cmd(s),因为p存放的不是“s存放的地址”,而是
- s本身的地址。详细查看“彻底搞定C指针”的第4篇。
- */
- get_cmd(&s);
- len = split_string(s,cmd);
-
- while(strcmp(cmd[0],"quit") != 0)
- {
- if(strcmp(cmd[0],"put") == 0)
- {
- char filename[100];
- strcpy(filename,cmd[1]);
- send_file(filename);
- }
-
- printf("ftp>");
- get_cmd(&s);
- len = split_string(s,cmd);
- }
-
- close(sockfd);
- exit(0);
-
- }
- int connect_to_server(char * ip)
- {
- struct hostent *host;
- printf("Connect to server……\n");
- /*建立IP地址*/
- host = gethostbyname(ip);
- if(host == NULL)
- {
- herror("gethostbyname error!");
- exit(1);
- }
- /*初始化服务器地址信息*/
- adr_srvr.sin_family = AF_INET;
- adr_srvr.sin_port = htons(port);
- adr_srvr.sin_addr = *((struct in_addr *)host->h_addr);
- bzero(&(adr_srvr.sin_zero),8);
-
- /*建立socket*/
- sockfd = socket(AF_INET,SOCK_DGRAM,0);
- if(sockfd == -1)
- {
- perror("socket error!");
- exit(1);
- }
- return 1;
- }
- void send_file(char *_filename)
- {
- FILE *fp;
- int send_ret;
- char buf[256];
- char str1[80];
- fp = fopen(_filename,"r");
- if(fp == NULL)
- {
- perror("open failed!");
- return ;
- }
- //读取数据传递给UDPserver
- printf("Sending……\n");
- while(fgets(str1,256,fp)!=NULL)
- {
- //printf("%s\n",str1);
- sprintf(buf,"%s",str1);
-
- send_ret = sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&adr_srvr,sizeof(adr_srvr));
-
- if(send_ret < 0)
- {
- perror("sendto error!");
- return;
- }
- }
- printf("Finished!\n");
- sprintf(buf,"stop\n");
-
- send_ret = sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&adr_srvr,sizeof(adr_srvr));
-
- if(send_ret < 0)
- {
- perror("sendto error!");
- return ;
- }
- fclose(fp);
- }