代码改变世界

文件传输

2013-10-08 22:07  崔靖  阅读(308)  评论(0)    收藏  举报

文件传输(基于TCPIP,多用户同时登陆,验证登陆,删除用户,注册用户,修改密码,显示传输进度,)

 

//client.c

#include "client_do.h"
#include "common.h"
int flag_login = 0;
int main(int argc, char **argv)
{
    if(3 != argc)
    {
        printf("Usage : %s <PORT> <SERVER IP>\n", argv[0]);
        exit(-1);
    }


    int my_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == my_fd)
    {
        perror("socket");
        exit(-1);
    }

    struct sockaddr_in ser_addr = {0};

    ser_addr.sin_family      = AF_INET;
    ser_addr.sin_port        = htons(atoi(argv[1]));
    ser_addr.sin_addr.s_addr = inet_addr(argv[2]);
   
    int len = sizeof ser_addr;

    if(-1 == connect(my_fd, (struct sockaddr*)&ser_addr, len))
    {
        perror("connect");
        exit(-1);
    }


    char buf[100] = {0};
    int  temp =0;
        BUF buf_tra;
    while(1)
    {
       
        if(flag_login ==0)
        {       
                   printf("输入 1 >  ===    登录用户    ===\n");
                   printf("输入 2 >  ===    注册用户    ===\n");
                   printf("输入 3 >  ===    删除用户    ===\n");
                   printf("输入 4 >  ===    修改密码    ===\n");
                   printf("您的选择是: ");
  
                     char a[3]={0};
                     fgets(a,3,stdin);
            switch (a[0])
            {
                case '1':
                    do_login(my_fd);break;
                case '2':
                    do_signin(my_fd);break;
                case '3':
                    do_delete(my_fd);break;
                case '4':
                    do_changepass(my_fd);break;

                default:
                    {
                        printf("输入错误!\n");
                    };break;
            }
           
        }       

        if(1==flag_login)
        {
           
            printf("mytftp> ");fflush(stdout);
            gets(buf);
            if(0 == strncmp("put", buf, 3))
                do_put(buf+4, my_fd);
            else
            if(0 == strncmp("get", buf, 3))
                do_get(buf+4, my_fd);
            else
            if(0 == strncmp("list", buf, 4))
                do_list(my_fd);
            else
            if(0 == strncmp("help", buf, 4) || 0 == strcmp("?", buf))
                do_help();
            else
            if(0 == strncmp("quit", buf, 4) || 0 == strcmp("q", buf))
                 {
                    flag_login = 0;       
                    bzero(&buf_tra,BUF_SIZE);
                    buf_tra.type = QUIT;
                    write(my_fd, &buf_tra, BUF_SIZE);
                 }
            else
            if(*buf != 0)
                printf("command error!\n");
        }   
    }   
}

 

//client_do.c

#include "client_do.h"
#include "common.h"
extern flag_login ;
void do_put(const char *file_name, int ser_fd)
{

    int fd = open(file_name, O_RDONLY);
    if(-1 == fd)
    {
        perror("error");   
        return;
    }
   

    BUF buf = {PUT};
    strcpy(buf.data,file_name);
    write(ser_fd, &buf, BUF_SIZE);
    struct stat s;
    if(-1 ==stat(file_name,&s))
    {
        perror("stat");
        exit(-1);
    }
    int size = s.st_size;
    long long n=1;
    int fen = 0,last_fen = 0;
    read(ser_fd, &buf, BUF_SIZE);
    if(buf.type == YES)
    {
        buf.type = BEGIN;
        while(buf.size = read(fd, buf.data, SIZE))
        {
        write(ser_fd, &buf, BUF_SIZE);
                    last_fen = fen ;
                fen = (int)((n++)*100*SIZE/size);

                if(fen != last_fen)
                {
            printf("%2d%%",(int)((n++)*100*SIZE/size));
                    fflush(stdout);
                    printf("\b\b\b");
                }
            }
        buf.type = END;
        write(ser_fd, &buf, BUF_SIZE);
        printf("\nFinish upload!\n");
    }
    else
    {
        printf("hello\n");
    }
   
}

void do_get(const char *file_name, int ser_fd)
{
    BUF buf = {GET};
    strcpy(buf.data, file_name);
    write(ser_fd, &buf, BUF_SIZE);

    read(ser_fd, &buf, BUF_SIZE);
    if(YES == buf.type)
    {
       
        int fd = open(file_name, O_CREAT|O_WRONLY, 0666);
        if(-1 == fd)
        {
       
        }
       
        int size = buf.size;
        long long n = 1;
            int fen = 0,last_fen = 0;
        while(1)
        {
   
            read(ser_fd, &buf, BUF_SIZE);
            if(END == buf.type)
                break;
            write(fd, buf.data, buf.size);
                    last_fen = fen ;
                    fen = (int)((n++)*100*SIZE/size);
                    if(fen != last_fen)
                    {
                printf("%2d%%",fen);fflush(stdout);
                    printf("\b\b\b");
                         }
                   
        }
        printf("\n");
        printf("Finish download!\n");
        close(fd);
    }
    else
        printf("no such file !\n");
}

void do_list(int ser_fd)
{
    BUF buf = {LIST};
    write(ser_fd, &buf, BUF_SIZE);

    while(1)
    {
        read(ser_fd, &buf, BUF_SIZE);
        if(END == buf.type)
            break;
        printf("%s ", buf.data);
    }

    printf("\n");
}

void do_help(void)
{
    printf("\n*********************************\n");
    printf("*    get : download    *\n");
    printf("*    put : upload    *\n");
    printf("*    help: help        *\n");
    printf("*    list: list        *\n");
    printf("*********************************\n\n");
}
int do_login( int my_fd)  
{
   
    NAME_BUF user;
    bzero(&user,NAME_SIZE);
    user.type = LOGIN;
    write(my_fd,&user,NAME_SIZE);
    printf("输入登录名: ");fflush(stdout);
    gets(user.name);
    printf("输入密码: ");
    gets(user.pass);
    user.type = BEGIN;
    write(my_fd,&user,NAME_SIZE);
    read(my_fd,&user,NAME_SIZE);
    if(user.type == YES)
        {
            printf("登录成功!\n");
            flag_login = 1;
            return TRUE;
        }
    else
        {
            printf("登录失败!\n");
            return FALSE;
        }

}
int do_signin(int my_fd) 
{

    NAME_BUF user;
    bzero(&user,NAME_SIZE);
    user.type = SIGNIN;
    write(my_fd,&user,NAME_SIZE);

    printf("输入注册名: ");fflush(stdout);
    gets(user.name);
    printf("输入注册密码: ");
    fflush(stdout);
    gets(user.pass);
    user.type = BEGIN;
    write(my_fd,&user,NAME_SIZE);
    read(my_fd,&user,NAME_SIZE);
    if(user.type == YES)
        {
            printf("注册成功!\n");
            return TRUE;
        }
    else
        {
            printf("注册失败!\n");
            return FALSE;
        }

   
}         
int do_delete(int my_fd)     
{
     NAME_BUF user;
    bzero(&user,NAME_SIZE);
    user.type = DELETE;
    write(my_fd,&user,NAME_SIZE);


    printf("输入删除用户名: ");
    fflush(stdout);
    gets(user.name);

    user.type = BEGIN;
    write(my_fd,&user,NAME_SIZE);
   
    read(my_fd,&user,NAME_SIZE);
    if(user.type == YES)
        {
            printf("删除成功!\n");
            return TRUE;
        }
    else
        {
            printf("删除失败!\n");
            return FALSE;
        }
}  

int do_changepass(int my_fd)
{
    NAME_BUF user;
    bzero(&user,NAME_SIZE);
    user.type = CHANGE;
    write(my_fd,&user,NAME_SIZE);


    printf("输入用户名: ");
    fflush(stdout);
    gets(user.name);
    printf("输入新密码:  ");
    fflush(stdout);
    gets(user.pass);
      printf("\n");
    user.type = BEGIN;
    write(my_fd,&user,NAME_SIZE);

    read(my_fd,&user,NAME_SIZE);
    if(user.type == YES)
        {
            printf("修改成功!\n");
            return TRUE;
        }
    else
        {
            printf("修改失败!");
            return FALSE;
        }
}

//client_do.h

 

#ifndef _client_do_h_
#define _client_do_h_

void do_put(const char *file_name, int ser_fd);
void do_get(const char *file_name, int ser_fd);
void do_list(int ser_fd);
void do_help(void);
int do_login( int my_fd);
int do_signin(int my_fd);
int do_delete(int my_fd);
int do_changepass(int my_fd);

#endif

 

//common.h

#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>


typedef enum mytype{LOGIN=2,GET,PUT,LIST,YES,NO,BEGIN,END,DELETE,SIGNIN,CHANGE,QUIT}TYPE;
#define SIZE 100
#define TRUE 1
#define FALSE 0

typedef struct buf{
    TYPE type;
    int size;
    char data[SIZE];
}BUF;


#define NAME_LONG 20
typedef struct name{

    TYPE type;
    char name[NAME_LONG];
    char pass[NAME_LONG];
    int size;
}NAME_BUF;


#define BUF_SIZE sizeof(BUF)
#define NAME_SIZE sizeof(NAME_BUF)
#endif

 

 

//=================================//

//server.c

#include "common.h"
#include "server_do.h"
#include "clist.h"
int count = 0;

ClistPtr head;
void *fun(void *p)
{
        BUF buf;
        NAME_BUF user;
    int client_fd = *((int*)p);
    int flag_login = 0;
    int do_login(int client_fd)
    {
        NAME_BUF user;
        read(client_fd,&user,NAME_SIZE);
   
        if(user.type == BEGIN)
        {
            ClistPtr p = head->next ;
            while(NULL != p)
            {
                if(strcmp(p->name,user.name)==0)
                    {
                        if(strcmp(p->pass,user.pass)==0)
                        {   
                            user.type = YES;
                            write(client_fd,&user,NAME_SIZE);
                            printf("login success\n");
                            flag_login = 1;
                            return 0;
                        }
                   
                        else
                        {
                            user.type = NO;
                            write(client_fd,&user,NAME_SIZE);
                            printf("passwd is error\n");
                            user.size = 0;//密码错误a
                            return 0;
                        }

                    }
                p = p->next;
            }
       
            printf("no such user\n");
            user.type = NO;
            user.size = 1;  //无该用户名
            write(client_fd,&user,NAME_SIZE);
            return -1;
        }
        else
        {
            printf("login fail\n");
            exit(-1);
        }
   
    }
    while(1)
    {
               if(flag_login == 0)
                {  
                        bzero(&user,NAME_SIZE);
                        read(client_fd,&user,NAME_SIZE);
                    switch (user.type)
                        {  
                                case LOGIN:
                                        do_login(client_fd);break;
                                case SIGNIN:
                                        do_signin(client_fd);break;
                                case DELETE:
                                        do_delete(client_fd);break;
                                case CHANGE:
                                        do_change(client_fd);break;
                                default :
                                        {  
                                                perror("login ");
                                                exit(-1);
                                        }  
                        }  
                }  
                if(flag_login ==1)
                {  
                        bzero(&buf,BUF_SIZE);
                        read(client_fd, &buf, BUF_SIZE);

                        switch (buf.type)
                        {  
                        case PUT:
                                do_put(buf.data, client_fd);break;
                        case GET:
                                do_get(buf.data, buf.size, client_fd);break;
                        case LIST:
                               do_list(client_fd);break;
                        case QUIT:
                                flag_login = 0;
            }
        }
    }
}

int main()
{
    int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == listen_fd)
    {
        perror("socket");
        exit(-1);
    }

    struct sockaddr_in my_addr = {0}, client_addr = {0};

    my_addr.sin_family      = AF_INET;
    my_addr.sin_port        = htons(888);
    my_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
   
    int len = sizeof my_addr;

    if(-1 == bind(listen_fd, (struct sockaddr*)&my_addr, len))
    {
        perror("bind");
        exit(-1);
    }

    listen(listen_fd, 100);


    printf("listen...............\n");
    int count = 0;
    create_list(&head);
    read_user();
    while(1)
    {
        int client_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &len);
        if(-1 == client_fd)
        {
            perror("accept");
            exit(-1);
        }

       
        pthread_t t;
        pthread_create(&t, NULL, fun, &client_fd);
    }
}

 

//serder_do.c

#include "server_do.h"
#include "common.h"
#include "clist.h"

extern ClistPtr head;

void do_get(const char *file_name, int len, int client_fd)
{
    BUF buf = {0};
    int fd = open(file_name, O_RDONLY);//打开文件
    if(-1 == fd)
    {
        buf.type = NO;
        write(client_fd, &buf, BUF_SIZE);
    }
    else
    {
        buf.type = YES;
        struct stat s;
        if(-1 == stat(file_name, &s))
        {
            perror("stat");
            exit(-1);
        }

        buf.size = s.st_size;
        write(client_fd, &buf, BUF_SIZE);
       
        buf.type = BEGIN;
        while(buf.size = read(fd, buf.data, SIZE))
            write(client_fd, &buf, BUF_SIZE);
        close(fd);
        buf.type = END;
        write(client_fd, &buf, BUF_SIZE);
    }
}

void do_put(const char *file_name,int client_fd)
{
    BUF buf;
    int fd = open(file_name, O_CREAT | O_WRONLY, 0666);
    if(-1 == fd)
    {
        buf.type = NO;
        buf.size = errno;
        write(client_fd, &buf, BUF_SIZE);
    }
    else
    {
        struct stat s;
        if(-1 == stat(file_name, &s))
        {
            perror("stat");
            exit(-1);
        }

        buf.type = YES;
        buf.size = s.st_size;
        write(client_fd, &buf, BUF_SIZE);

        while(1)
        {
            if(-1 == read(client_fd, &buf, BUF_SIZE))
            {
                perror("read put:");
                exit(-1);
            }
            if(END != buf.type)
                   write(fd, buf.data, buf.size);   
            else
                break;
        }
        close(fd);
    }
}

void do_list(int client_fd)
{
    DIR *dp = opendir(".");
   

    struct dirent *dp_r;
    BUF buf = {0};
    buf.type = BEGIN;
    while(dp_r = readdir(dp))
    {
        strcpy(buf.data,dp_r->d_name);
        write(client_fd, &buf, BUF_SIZE);   
    }
    buf.type = END;
    write(client_fd, &buf, BUF_SIZE);   
    closedir(dp);
}
/*
int do_login(int client_fd)
{
    NAME_BUF user;
    read(client_fd,&user,NAME_SIZE);
   
    if(user.type == BEGIN)
    {
        ClistPtr p = head->next ;
        while(NULL != p)
        {
            if(strcmp(p->name,user.name)==0)
                {
                    if(strcmp(p->pass,user.pass)==0)
                    {   
                        user.type = YES;
                        write(client_fd,&user,NAME_SIZE);
                        printf("login success\n");
                        flag_login = 1;
                        return 0;
                    }
                   
                    else
                    {
                        user.type = NO;
                        write(client_fd,&user,NAME_SIZE);
                        printf("passwd is error\n");
                        user.size = 0;//密码错误a
                        return 0;
                    }

                }
            p = p->next;
        }
       
        printf("no such user\n");
        user.type = NO;
        user.size = 1;  //无该用户名
        write(client_fd,&user,NAME_SIZE);
        return -1;
    }
    else
    {
        printf("login fail\n");
        exit(-1);
    }
   
}
*/
int do_signin(int client_fd)
{
       FILE * fd =fopen("user.txt","a+");
        if(fd==NULL)
        {
                printf("open\n");
                exit(-1);
        }

    NAME_BUF user;
    read(client_fd,&user,NAME_SIZE);
    if(user.type == BEGIN)
    {
        insert_list(head,user.name,user.pass);
        user.type = YES;
        write(client_fd,&user,NAME_SIZE);   
    //    write(fd,user.name,NAME_SIZE);
    //    write(fd,user.pass,NAME_SIZE);
        fprintf(fd,"%s\t%s\n",user.name,user.pass);
            fclose(fd);
    }   
    else
    {
        user.type = NO;
        write(client_fd,&user,NAME_SIZE);
    }
   
}
int do_delete(int client_fd)
{
    FILE * fd = fopen("user.txt","w+");
    NAME_BUF user;
//    ClistPtr q = head->next;
    ClistPtr p = head->next;
    read(client_fd,&user,NAME_SIZE);
    if(user.type == BEGIN)
    {
        while(NULL != p)
        {
            if(strcmp(user.name,p->name)==0)
            {
                delete_list(head,p->name);
                    ClistPtr q = head->next;
                while(NULL != q)
                {
                    fprintf(fd,"%s\t%s\n",q->name,q->pass);
                    q = q->next;
                }
                fclose(fd);
                user.type = YES;
                write(client_fd,&user,NAME_SIZE);
                return 0;
            }
           
            p = p->next;
        }

        fclose(fd);
        //show_list(head);
        user.type = NO;
        write(client_fd,&user,NAME_SIZE);
        return -1;
   
    }

    else
    {
        printf("delete error\n");
        exit(-1);
    }
}
int do_change(int client_fd)
{
    FILE * fd = fopen("user.txt","w+");
    if(fd ==NULL)
    {
        printf("fopen\n");
        exit(-1);
    }
    NAME_BUF user;
    ClistPtr p = head->next,q;
    read(client_fd,&user,NAME_SIZE);
    if(user.type == BEGIN)
    {
        while(NULL != p)
        {
            if(strcmp(user.name,p->name)==0)
            {
                bzero(p->pass,NAME_LONG);
                strcpy(p->pass,user.pass);
                q = head->next;
                while(NULL != q)
                {
                    fprintf(fd,"%s\t%s\n",q->name,q->pass);
                    q = q->next;
                }
                fclose(fd);
                user.type = YES;
                write(client_fd,&user,NAME_SIZE);
                return 0;
            }   
            p = p->next;
        }
      

        user.type = NO;
        user.size = 0;
        write(client_fd,&user,NAME_SIZE);
        return -1;

    }   
    else
    {   
        user.type = NO;
        user.size = 1;
        write(client_fd,&user,NAME_SIZE);
        return -1;
    }
}

int read_user(void)
{   
    int n = 0;
    NAME_BUF user;
    FILE * fd = fopen("user.txt","r");
    fseek(fd,0,SEEK_SET);
    if(fd==NULL)
    {
        printf("open\n");
        exit(-1);
    }
    while(-1 !=(n = fscanf(fd,"%s\t%s",user.name,user.pass)))
    {
        insert_list(head,user.name,user.pass);
        printf("%s %s\n",user.name,user.pass);
    }
    //show_list(head);
    fclose(fd);
}

 

//clist.c

//带头结点的链表
#include "clist.h"

int create_list(ClistPtr *head)
{
    if(NULL == (*head = (ClistPtr)malloc(sizeof(Clist))))
        perror("*head");

    (*head)->next = NULL;   
    return TRUE;
}

//原本没有最大限制,自己指定允许最大为5
int isfull_list(ClistPtr head)
{
    int count = 0;
    ClistPtr p = head->next;
    while(NULL != p)
    {
        count++;
        if(5 == count)
        {
            return 1;
        }
        p = p->next;
    }
    return 0;
}

int isempty_list(ClistPtr head)
{
    return head->next == NULL ? TRUE:FALSE;
}
int destory_list(ClistPtr head)
{
    if(isempty_list(head))
    {
        printf("The list is empty\n");
        return FALSE;
    }
    ClistPtr p = head,q;
    while(NULL != p)
    {
        q = p;
        p = p->next;
        free(q);
    }
    free(q);
    return TRUE;
}

//采用头插法
int insert_list(ClistPtr head, char *name , char *pass)
{
   
    if(isfull_list(head))
    {
        printf("The list is full\n");
         return FALSE;
    }
    ClistPtr p = head,q;
    if(NULL == (q = (ClistPtr)malloc(sizeof(Clist))))    
    perror("q");
    strcpy(q->name,name);
    strcpy(q->pass,pass);
   
    q->next = p->next;
    p->next = q;
    return TRUE;
}

//根据用户名删除该用户的信息
int delete_list(ClistPtr head, char *name)
{
    if(isempty_list(head))
    {  
        printf("The list is empty\n");
        return FALSE;
    }  

    ClistPtr p,q;
    p = head;
    q  = head->next;
    while(NULL != q)
    {
        if(strcmp(name,q->name)==0)
        {
            p->next = q->next;
            free(q);
            return TRUE;
        }       
        p = q;
        q = q->next;
       
    }
    printf("%s is not exit!\n",name);
    return FALSE;
}
int get_ele(ClistPtr head, char *name, ClistPtr *ret)
{
    if(isempty_list(head))
    {  
        printf("The list is empty\n");
        return FALSE;
    }  

    ClistPtr p = head->next;
    while(NULL != p)
    {
        if(strcmp(name,p->name)==0)
        {
            *ret = p;
            return TRUE;
        }
        p = p->next;
    }
    return FALSE;
}
int show_list(ClistPtr head)
{
    if(isempty_list(head))
    {  
        printf("The list is empty\n");
        return FALSE;
    }  

    ClistPtr p = head->next;
    while(NULL != p)
    {
        printf("%s\t",p->name);
        printf("%s\n",p->pass);
        p = p->next;
    }

    return TRUE;
}

 

//clist.h

#ifndef _common_h_
#define _common_h_
 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define NAME_SIZES 20
#define PASS_SIZES 20

#define TRUE  1
#define FALSE 0

typedef struct clist
{
    char name[NAME_SIZES];
    char pass[PASS_SIZES];
    struct clist * next;
}Clist,*ClistPtr;


int create_list(ClistPtr *head);
int destory_list(ClistPtr head);
int insert_list(ClistPtr head, char *name , char *pass);
int delete_list(ClistPtr head, char *name);
int get_ele(ClistPtr head, char *name, ClistPtr *p);
int show_list(ClistPtr head);
int isfull_list(ClistPtr head);
int isempty_list(ClistPtr head);

#endif

//server_do.h

#ifdef _SERVER_DO_H
#define _SERVER_DO_H


void do_get(const char *file_name, int len, int client_fd);
void do_put(const char *file_name, int ser_fd, int client_fd);
void do_list(int client_fd);
int do_signin(int client_fd);
int do_delete(int client_fd);
int do_change(int client_fd);
int read_user(void);

#endif

//common.h

#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>


typedef enum mytype{LOGIN=2,GET,PUT,LIST,YES,NO,BEGIN,END,DELETE,SIGNIN,CHANGE,QUIT}TYPE;
#define SIZE 100
#define TRUE 1
#define FALSE 0

typedef struct buf{
    TYPE type;
    int size;
    char data[SIZE];
}BUF;


#define NAME_LONG 20
typedef struct name{

    TYPE type;
    char name[NAME_LONG];
    char pass[NAME_LONG];
    int size;
}NAME_BUF;


#define BUF_SIZE sizeof(BUF)
#define NAME_SIZE sizeof(NAME_BUF)
#endif