linux系统编程总结题之ftp服务器的实现

能力要求:
1.要求熟练掌握c语言编程
2.熟练运用linux系统编程

基本思路,在socket编程的框架上,加入对命令的处理之后进行文件的读取,创建,程序调用等;

问题1:如何处理指令?
写一个函数调用字符串 相等,分割等方法。
再返回相对应值给switch进行不同指令的处理。
问题2:如何保存命令行处理结果?
采用结构体,将指令存在msg.command内,处理结果保存在msg.data内。
在调用open read 等 将读取到的文件存放 到data中。

遇到的问题
1.终止的指令应该要用Ctrl C 不能用Ctrl Z 不然端口会费掉
2.要对msg结构体memset 不然会一直保留旧的data
3.char *file int fd FILE *file 用处要分清不然连bug都看不懂
4。在getfile进行类似cd a.c 这种指令的操作时,如何保留我原来的command不被改变。
5.要多次写demo备份,不然会前功尽弃。导致之前的代码功能报废,严重甚至连之前的代码思路都被打断。
6.char *a char b[10] 怎么把command的保存住不被改变, 指针不要成为野指针 要malloc
7结构体定义 struct Msg msg
8。popen system 区别
9对get put 命令处理时的 文件读取 msg.data的先后顺序

ftp的服务器代码实现。


#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define LS 1
#define PWD 2

#define GET  4
#define PUT 5
#define CD 3

#define QUIT 6
struct Msg
{
        int type;
        char command[2048];
        char data[2048];// read readbuf 
}msg;


int getType(char *cmd)
{
        if(!strcmp("ls",cmd))  return LS;
        if(!strcmp("pwd",cmd))  return PWD;

        if(strstr(cmd,"cd"))  return CD;
        if(strstr(cmd,"get"))  return GET;
        if(strstr(cmd,"put"))  return PUT;

        if(!strcmp("quit",cmd))  return QUIT;

        return -1;
}
char *getfile(char *str)
{
        char *p;
        p = strtok(str, " ");
        p = strtok(NULL, " ");

        return p;

}

void handle_msg(struct Msg msg,int c_fd)
{	printf(".......................................\n");
//	char *file = getfile(&msg.data);
        int type = getType(msg.command);
//        printf("you input command is : %s",msg.command);
        switch(type)
        {
                case LS:
                case PWD:{

                       FILE * file = popen(msg.command,"r");
			memset(msg.data,0,sizeof(msg.data));
                        fread(msg.data,sizeof(char),2048,file);
			write(c_fd,&msg,sizeof(msg));
			printf("%s",msg.data);
                        break;
                        }
                case CD:{
			char *dir = getfile(msg.command);
			
			printf("dir: %s \n",dir);
			chdir(dir);			
                        break;}

                case GET:{
			char tmp[2048] ;
			strcpy(tmp,msg.command);
                        char  *file = getfile(msg.command);
                        if(access(file,0) == -1){
                                printf("file not exist\n");
                        }else if(access(file,0) == 0){

                                int fd =open(file,O_RDWR);
//				memset(msg.data,0,sizeof(msg.data));
                                read(fd,msg.data,sizeof(msg.data));
                          //     	strcpy(msg.command,tmp);
				strcpy(msg.command,tmp);
				write(c_fd,&msg,sizeof(msg));
				
                                printf("cmd:%s \n data:%s \n",msg.command,msg.data);
                                printf("get file successed\n");
                        break;}}
                case PUT:{
			printf("puting------------------------");
			printf("command:%s \n data: %s \n",msg.command,msg.data);
			 char *file = getfile(msg.command);
                        int fd = open(file,O_RDWR|O_CREAT,0600);
                        write(fd,msg.data,sizeof(msg.data));
			printf("command:%s \n data: %s \n",msg.command,msg.data);
                        printf("put file over!\n");

                        

                        break;}
                case 6:{

                        break;}
                default:
                        printf("your input is error ");
                        break;
        }
}




int main(int argc, char ** argv)
{

        int s_fd;
        int c_fd;
        int nread;
        struct sockaddr_in s_addr;
        struct sockaddr_in c_addr;
	struct Msg msg;
        memset(&s_fd,0,sizeof(struct sockaddr_in));
        memset(&c_fd,0,sizeof(struct sockaddr_in));

        //1.socket 创建socket
        s_fd = socket( AF_INET ,SOCK_STREAM,0);
//sever send message
        if(s_fd == -1){
                perror("error");
                exit(-1);
        }
//  int socket(int domain, int type, int protocol);


        s_addr.sin_family = AF_INET;
        s_addr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1],&s_addr.sin_addr);
        printf("create socket  successed \n");
        //2.bind 绑定

//int bind(int sockfd, const struct sockaddr *addr,
  //              socklen_t addrlen);
        bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in ));
        printf("bind   successed \n");
        //3.listen 
//    int listen(int sockfd, int backlog);

        listen(s_fd,10);
        printf("listen ok\n");
        //4.accept

// int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
// client  accept message
         int clen = sizeof(struct sockaddr_in);
                //5.read
                c_fd = accept(s_fd,(struct sockaddr *)&s_addr,&clen);
                if(c_fd == -1){
                        perror("accept");

                }
        while(1){

                printf("get connect %s\n",inet_ntoa(c_addr.sin_addr));

//调用线程实现双方同步聊天,用read write交流

                        if(fork()==0){
                                while(1){
                                        //6.write
                                        memset(&msg,0,sizeof(msg));//每次初始化缓存,防止内容重复
                                        printf(">");
                                        gets(msg.command);
                                        write(c_fd,&msg,sizeof(msg));
                                }
                        }


                        while(1){
                                memset(&msg,0,sizeof(msg)); //
                                nread = read(c_fd,&msg,sizeof(msg));
                                if(nread == 0){

                                        perror("read");
					sleep(3);
                                }else {
                                        printf("your command :%s\n",msg.command);
					handle_msg(msg,c_fd);
                                }
                        }


        }
//	close(s_fd);
//	close(c_fd);
        return 0;
}

客户端的代码实现

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define LS 1
#define PWD 2

#define GET  4
#define PUT 5
#define CD 3

#define QUIT 6

#define LLS 7
#define LCD 8

#define WRONG -1
struct Msg
{
        int type;
        char command[2048];
        char data[2048];// read readbuf 
}msg;


getType(char *cmd)
{
        if(!strcmp("ls",cmd))  return LS;
        if(!strcmp("pwd",cmd))  return PWD;

        if(strstr(cmd,"cd"))  return CD;
        if(strstr(cmd,"get"))  return GET;
        if(strstr(cmd,"put"))  return PUT;

        if(!strcmp("quit",cmd))  return QUIT;

        if(!strcmp("lls",cmd))  return LLS;
        if(!strcmp("lcd",cmd))  return LCD;
       
	 return -1;
}
char *getfile(char *str)
{
        char *p;
        p = strtok(str, " ");
        p = strtok(NULL, " ");

        return p;

}


handle_msg(struct Msg msg,int c_fd)
{
//      char *file = getfile(&msg.data);
        int type = getType(msg.command);
      //  printf("you input command is : %s",msg.command);
	printf("you type is %d \n",type);
        switch(type)
        {
                case LS:
                case PWD:
			write(c_fd,&msg,sizeof(msg));
                        break;
                case CD:{

			write(c_fd,&msg,sizeof(msg));
                        break;}

                case GET:{
			write(c_fd,&msg,sizeof(msg));
                        break;}
                case PUT:{
			char tmp[2048] ;
                        strcpy(tmp,msg.command);
                        char  *file = getfile(msg.command);
                        if(access(file,0) == -1){
                                printf("file not exist\n");
                        }else if(access(file,0) == 0){

                                int fd =open(file,O_RDWR);
//                              memset(msg.data,0,sizeof(msg.data));
                                read(fd,msg.data,sizeof(msg.data));
                          //            strcpy(msg.command,tmp);
                                strcpy(msg.command,tmp);
                                write(c_fd,&msg,sizeof(msg));

                                printf("cmd:%s \n data:%s \n",msg.command,msg.data);
                                printf("put file successed\n");
                        	break;}
			}
                case LLS:{
			system("ls");
                        break;}
		case LCD :
			{
			char *dir = getfile(msg.command);
                        
                        printf("dir: %s \n",dir);               
                        chdir(dir);

			break;
			}
                case WRONG:
                        printf("your input is error ");
                        break;
		default : break;
        }
        return 0;
}

read_handle_msg(struct Msg msg,int c_fd)
{
	 int type = getType(msg.command);
      //  printf("you input command is : %s",msg.command);
        switch(type)
        {
                case LS:
                case PWD:printf("-------------------------------\n");
			 printf("command %s\n",msg.command);
                         printf("\n%s\n",msg.data);
                         printf("-------------------------------\n");
                        
                        break;
                case CD:{

                        break;}

                case GET:{
			char *file = getfile(msg.command);
			int fd = open(file,O_RDWR|O_CREAT,0600);
			write(fd,msg.data,sizeof(msg.data));
			printf("get file over!\n");
                        break;}
                case PUT:{
			
			break;	
			}
                case 6:{

                        break;}
                default:
                        break;
        }
        return 0;
}

int main(int argc, char ** argv)
{

        int c_fd;
        int nread;

        struct sockaddr_in c_addr;
	struct Msg msg;
        memset(&c_fd,0,sizeof(struct sockaddr_in));

        //1.socket
        c_fd = socket( AF_INET ,SOCK_STREAM,0);
//sever send message
        if(c_fd == -1){
                perror("socket");
                exit(-1);
        }
//  int socket(int domain, int type, int protocol);


        c_addr.sin_family = AF_INET;
        c_addr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1],&c_addr.sin_addr);
        printf("create socket  successed \n");

//    int connect(int sockfd, const struct sockaddr *addr,
  //                 socklen_t addrlen);

         if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr))== -1)//客户端 直接用connect
        {
                perror("connect");
                        exit(-1);
        }
        while(1){

                        if(fork()==0){
                                while(1){
                                        //6.write
                                        memset(&msg,0,sizeof(msg));//每次初>始化缓存,防止内容重复
                                        printf(">");
                                        gets(msg.command);
                                        handle_msg(msg,c_fd);
//					write(c_fd,&msg,sizeof(msg));
//					write(c_fd,msg.command,sizeof(msg.command));
                                }
                        }


                        while(1){
                               memset(&msg,0,sizeof(msg)); //
                                nread = read(c_fd,&msg,sizeof(msg));
                                if(nread == -1){

                                        perror("read");
					sleep(3);
                                }else {
                                 //     printf("your command :%s\n",msg.command);
					read_handle_msg(msg,c_fd);
			/*		printf("-------------------------------\n");
					printf("\n%s\n",msg.data);
					printf("-------------------------------\n");*/
                                }
                        }


        }
        //6.write


        printf("connect  successed \n");
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值