文件服务器

1.文件服务器
2.实现文件的上传下载,模拟百度云。
直接看代码吧:
client端
//client.c

include “Dclient.h”

include “Fclient.h”

include “Debug.h”

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include “type.h”

include

include “Debug.h”

sqlite3 *db = NULL;
pthread_mutex_t list_lock;
void *wait_for_iprequest(void *x)
{
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sockfd)
{
perror(“socket”);
return NULL;
}

struct sockaddr_in serveraddr = {0}, clientaddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = INADDR_ANY;//inet_addr("0.0.0.0");
serveraddr.sin_port = htons(DATABASEPORT);
int len = sizeof serveraddr;

int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on , sizeof on);
if(-1 == bind(sockfd, (struct sockaddr*)&serveraddr, len) )
{
    perror("bind");
    return NULL;
}

char buf[BUFSIZE] = {0};
while(1)
{
    recvfrom(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&clientaddr, &len);
    sendto(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&clientaddr, len);
}

}

void *func(void *arg)
{
int clientfd = (int)arg;

while(1)
{
    char buf[BUFSIZE] = {0};
    int ret = read(clientfd, buf, BUFSIZE);
    if(0 == ret || -1 == ret)
        break;


    if(0 == strncmp("register", buf, 8) )
    {       
        char name[20] = {0};
        char pass[20] = {0};
        sscanf(buf, "%*s%s%s", name, pass);
        pthread_mutex_lock(&list_lock);
        char sql[BUFSIZE] = {0};
        sprintf(sql, "insert into userpass values('%s', '%s');", name, pass);
        char *errmsg;
        if(sqlite3_exec(db, sql,  NULL,  NULL, &errmsg) !=  SQLITE_OK)
        {
            printf("error :  %s\n",  errmsg);
            exit(-1);
        }

        bzero(sql, BUFSIZE);
        sprintf(sql, "create table %s(filename);", name);
        if(sqlite3_exec(db, sql, NULL,  NULL, &errmsg) !=  SQLITE_OK)
        {
            printf("error :  %s\n",  errmsg);
            exit(-1);
        }


        pthread_mutex_unlock(&list_lock);
        strcpy(buf, "ok");
        write(clientfd, buf, sizeof buf);
    }
    else
    if(0 == strncmp("changepass", buf, 10) )
    {       
        char name[20] = {0};
        char pass[20] = {0};
        char newpass[20] = {0};
        char sql[BUFSIZE] = {0};
        sscanf(buf, "%*s%s%s%s", name, pass, newpass);
        pthread_mutex_lock(&list_lock);

        bzero(sql, BUFSIZE);
        sprintf(sql, "update userpass set pass='%s' where name='%s' and pass='%s';",newpass,  name, pass);
        char *errmsg;
        if(sqlite3_exec(db, sql, NULL,  NULL, &errmsg) !=  SQLITE_OK)
        {
            printf("error :  %s\n",  errmsg);
            exit(-1);
        }


        pthread_mutex_unlock(&list_lock);
        strcpy(buf, "ok");
        write(clientfd, buf, sizeof buf);
    }
    else
    if(0 == strncmp("login", buf, 5) )
    {       
        char name[20] = {0};
        char pass[20] = {0};
        sscanf(buf, "%*s%s%s", name, pass);
        pthread_mutex_lock(&list_lock);

        char sql[BUFSIZE] = {0};
        sprintf(sql, "select * from userpass where name='%s' and pass='%s';", name, pass);
        char  *errmsg,**resultp;
        int  nrow,  ncolumn, i, j, index;
        if(sqlite3_get_table(db, sql,  &resultp,  &nrow, &ncolumn,  &errmsg) !=  SQLITE_OK)
        {
            printf("error :  %s\n",  errmsg);
            exit(-1);
        }

        pthread_mutex_unlock(&list_lock);
        strcpy(buf, nrow!=0?"OK":"no");
        write(clientfd, buf, sizeof buf);
    }
    else
    if(0 == strncmp("requestlist", buf, 11) )
    {
        char name[20] = {0};
        sscanf(buf, "%*s%s", name);
        char sql[BUFSIZE] = {0};
        sprintf(sql, "select * from %s;", name);
        char  *errmsg,**resultp;
        int  nrow,  ncolumn, i, j, index;
        if(sqlite3_get_table(db, sql,  &resultp,  &nrow, &ncolumn,  &errmsg) !=  SQLITE_OK)

// {
// printf(“error : %s\n”, errmsg);
// exit(-1);
// }

        bzero(buf, BUFSIZE);
        i = 1;
        for(;i<=nrow; i++)
        {
            strcat(strcat(buf, resultp[i]), " ");
        }

        write(clientfd, buf, sizeof buf);
    }
    else        
    if(0 == strncmp("adduserfile", buf, 11) )
    {
        char username[20] = {0};
        char filename[20] = {0};
        sscanf(buf, "%*s%s%s", username, filename);
        char sql[BUFSIZE] = {0};
        sprintf(sql, "insert into %s values('%s');", username, filename);
        char *errmsg;
        if(sqlite3_exec(db, sql,  NULL,  NULL, &errmsg) !=  SQLITE_OK)
        {
            printf("error :  %s\n",  errmsg);
            exit(-1);
        }
        strcpy(buf, "OK");
        write(clientfd, buf, sizeof buf);

    }
    else        
        strcpy(buf, "cmd err!\n");

}

}

extern void wait_for_iprequest(void);

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

if(SQLITE_OK != sqlite3_open("my.db", &db) )
{
    printf("%s\n", sqlite3_errmsg(db));
    return -1;
}

//create userpass table
char *errmsg;
if(sqlite3_exec(db, "create table userpass('name', 'pass');",  NULL,  NULL, &errmsg) !=  SQLITE_OK);

int pid = fork();
//子进程接收广播,父进程服务
if(0 == pid)
{
    wait_for_iprequest(NULL);
}
else
{

    int fd = socket(AF_INET, SOCK_STREAM, 0);//申请网络服务,获得套接字文件描述符fd
    if(-1 == fd)
    {
        perror("socket");
        return -1;
    }

    struct sockaddr_in serveraddr = {0}, clientaddr = {0};//准备好服务器的地址及端口描述
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");
    serveraddr.sin_port = htons(8888);//服务器软件绑定的端口
    int len = sizeof serveraddr;

    //set reuse
    int on = 1;
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);

    if(-1 == bind(fd, (struct sockaddr*)&serveraddr, len) )
    {
        perror("connect");
        return -1;
    }

    listen(fd, 10);//start wait

    pthread_mutex_init(&list_lock, NULL);

    while(1)
    {

        printf("waiting............\n");
        int clientfd = accept(fd, (struct sockaddr*)&clientaddr, &len);
        printf("incoming: %s\n", inet_ntoa(clientaddr.sin_addr) );

        pthread_t t;
        pthread_create(&t, NULL, func, (void*)clientfd);

    }   
}

}
//Fserver.c

include

include

include

include

include

include

include

include

include

include

include

include “Dclient.h”

include “type.h”

include “Debug.h”

include

ifndef DC

define DC

include “type.h”

typedef struct Dclient{
char IP[MAXLEN];
char username[MAXLEN];
}DC;

DC *open_Dclient(void);
//for client
int register_Dclient(DC *dc, const char *username, const char *passwd);
int login_Dclient(DC *dc, const char *username, const char *passwd);
int changepass_Dclient(DC *dc, const char *username, const char *passwd, const char *newpasswd);

//for Fserver
int requestlist_Dclient(DC *dc, const char *username, char *listbuf);
int adduserfile_Dclient(DC *dc, const char *username, const char *filename);

endif

//Debug.h

ifndef DEBUG

define DEBUG

include

ifdef DEBUG

#define Debug(format, args...)     printf(format, ##args)

else

#define Debug(format, args...)

endif

endif

//Fclient.h

ifndef FC

define FC

include “type.h”

typedef struct Fclient{
int sockfd;
}FC;

//for client
FC *open_Fclient();
int putfile_Fclient(FC *fd, const char *username, const char *filename);
int getfile_Fclient(FC *fd, const char *username, const char *filename);
int listfile_Fclient(FC *fd, const char *username, char *listbuf);

endif

//type.h

ifndef TYPE_

define TYPE_

define MAXLEN 20

define BUFSIZE 1024

define DATABASEPORT 8888

define FILESERVERPORT 9999

endif

//Dclient.c

include “Dclient.h”

include

include

include

include

include

include

include

include

include “Debug.h”

DC *open_Dclient(void)
{
char serverIP[20] = {0};
DC *dc = malloc(sizeof(DC));

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sockfd)
{
    perror("socket");
    return NULL;
}

struct sockaddr_in serveraddr = {0};
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("255.255.255.255");
serveraddr.sin_port = htons(DATABASEPORT);
int len = sizeof serveraddr;

int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof on);
struct timeval t = {5};
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof t);

char buf[] = {"database"};
while(1)
{
    sendto(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&serveraddr, len);
    if(-1 == recvfrom(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&serveraddr, &len) )
    {
        printf("database server not ready!\n");
        return NULL;
    }
    else
    {
        strcpy(serverIP, inet_ntoa(serveraddr.sin_addr));
        break;
    }
}

strcpy(dc->IP, serverIP);

return dc;

}

static int connect_server(DC *dc)
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);//申请网络服务,获得套接字文件描述符fd
if(-1 == sockfd)
{
perror(“socket”);
return -1;
}

struct sockaddr_in serveraddr = {0};//准备好服务器的地址及端口描述
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(dc->IP);//服务器IP地址
serveraddr.sin_port = htons(DATABASEPORT);//服务器软件绑定的端口
int len = sizeof serveraddr;

if(-1 == connect(sockfd, (struct sockaddr*)&serveraddr, len) )//连接服务器测试线路状态
{
    perror("connect");
    return -1;
}
return sockfd;

}
//for client
int register_Dclient(DC *dc, const char *username, const char *passwd)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;

char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s %s", "register", username, passwd);
write(sockfd, buf, sizeof buf);

read(sockfd, buf, sizeof buf);
if(0 == strcmp("OK", buf) )
    return 0;
else
    return -1;

}

int login_Dclient(DC *dc, const char *username, const char *passwd)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;

char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s %s", "login", username, passwd);
write(sockfd, buf, sizeof buf);

read(sockfd, buf, sizeof buf);
if(0 == strncmp("OK", buf, 2) )
    return 0;
else
    return -1;

}

int changepass_Dclient(DC *dc, const char *username, const char *passwd, const char *newpasswd)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;

char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s %s %s", "changepass", username, passwd, newpasswd);
write(sockfd, buf, sizeof buf);

read(sockfd, buf, sizeof buf);
if(0 == strcmp("OK", buf) )
    return 0;
else
    return -1;

}

//for Fserver
int requestlist_Dclient(DC *dc, const char *username, char *listbuf)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;

char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s", "requestlist", username);
write(sockfd, buf, sizeof buf);

read(sockfd, listbuf, sizeof buf);

return 0;

}

int adduserfile_Dclient(DC *dc, const char *username, const char *filename)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;

char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s %s", "adduserfile", username, filename);
write(sockfd, buf, sizeof buf);

read(sockfd, buf, sizeof buf);
if(0 == strcmp("OK", buf) )
    return 0;
else
    return -1;

}

//Fclient.c

include “Fclient.h”

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include “Debug.h”

//for client
FC *open_Fclient()
{
char FILESERVERIP[MAXLEN] = {0};

FC *fc = malloc(sizeof(FC));
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sockfd)
{
    perror("socket");
    return NULL;
}

struct sockaddr_in serveraddr = {0};
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("255.255.255.255");
serveraddr.sin_port = htons(FILESERVERPORT);
int len = sizeof serveraddr;

int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof on);
struct timeval t = {5};
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof t);

char buf[] = {"fileserver"};
while(1)
{
    sendto(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&serveraddr, len);
    if(-1 == recvfrom(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&serveraddr, &len) )
    {
        printf("file server not ready!\n");
        return NULL;
    }
    else
    {
        strcpy(FILESERVERIP, inet_ntoa(serveraddr.sin_addr));
        break;
    }
}

int Tcpsockfd = socket(AF_INET, SOCK_STREAM, 0);//申请网络服务,获得套接字文件描述符fd
if(-1 == Tcpsockfd)
{
    perror("socket");
    return NULL;
}

struct sockaddr_in Tserveraddr = {0};//准备好服务器的地址及端口描述
Tserveraddr.sin_family = AF_INET;
Tserveraddr.sin_addr.s_addr = inet_addr(FILESERVERIP);//服务器IP地址
Tserveraddr.sin_port = htons(FILESERVERPORT);//服务器软件绑定的端口
len = sizeof Tserveraddr;

if(-1 == connect(Tcpsockfd, (struct sockaddr*)&Tserveraddr, len) )//连接服务器测试线路状态
{
    perror("connect");
    return NULL;
}

fc->sockfd = Tcpsockfd;
return fc;

}

int putfile_Fclient(FC *fc, const char *username, const char *filename)
{
char buf[BUFSIZE] = {0};
sprintf(buf, “%s %s %s”, “put”, filename, username);
//send file put request
int ret = write(fc->sockfd, buf, sizeof buf);
//send file size
struct stat s;
ret = stat(filename, &s);
sprintf(buf, “%ld”, s.st_size);
ret = write(fc->sockfd, buf, sizeof buf);
//send file data
int fdx = open(filename, O_RDONLY);
int n = 0;
while(n = read(fdx, buf, sizeof buf) )
{

    ret =   write(fc->sockfd, buf, n);
}   
printf("成功上传 %s 文件!\n",filename);
close(fdx);

}

int getfile_Fclient(FC *fc, const char *username, const char *filename)
{
char buf[BUFSIZE] = {0};
sprintf(buf, “%s %s %s”, “get”, filename, username);
//send get request
write(fc->sockfd, buf, sizeof buf);
//recv file stat
read(fc->sockfd, buf, sizeof buf);
//if NO, continue;
if(0 == strncmp(“NO”, buf, 2) )
{
printf(“No such file on server !\n”);
return -1;
}
//if OK, recv file size
read(fc->sockfd, buf, sizeof buf);
int size = atoi(buf);
int filesize=size;
//read file data && save into a new file
int fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0666);
while(size)
{
//read data
int n = read(fc->sockfd, buf, sizeof buf);
//save data
write(fd, buf, n);

    size -= n;
}
printf("下载了一个文件!\n");
printf("文件大小为:%dByte\n", filesize);
close(fd);

}

int listfile_Fclient(FC *fc, const char *username, char *listbuf)
{
char buf[BUFSIZE] = {0};
sprintf(buf, “%s %s”, “list”, username);
//send get request
write(fc->sockfd, buf, sizeof buf);
read(fc->sockfd, listbuf, sizeof buf);
// printf(“%s\n”, buf);
return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值