网络通信小项目---TCP简单云盘

时间:2024-04-08 08:47:04

最近在学linux下的网络编程,做了一个小小的项目,记录一下。

项目名称:局域网下云盘

项目功能:用户输入用户名和密码登录,成功后连接文件服务器,进行文件的上传和下载

客户端:

开始界面:

网络通信小项目---TCP简单云盘

根据用户输入的命令进行相应的操作,将想要做的事情传递到服务器端,服务器将会处理用户的命令,并给予反馈。

       ------------------------------------------------------------------------------------------------------------------

//注册
int zhuce(int sockfd1)
{
    char buf[100] = {0};
    strcpy(buf,"1");
    write(sockfd1,buf,100);//向服务器发送1代表要进行注册
    printf("username&passwd> ");
    fflush(stdout);
    memset(buf,0,sizeof(buf));
    gets(buf);
    write(sockfd1,buf,100);//发送要注册的用户名和密码

    read(sockfd1,buf,100);//读取服务器的反馈
    if(0 == strncmp(buf,"ok",2))
    {
        printf("zhuce is ok\n");
    }
else if(0 == strncmp(buf,"no",2))
{
printf("zhuce is failed\n");
return 0;
}
    return 0;
}

       ----------------------------------------------------------------------------------------------------------------

//登录
int login(int sockfd1)
{
    char buf[100] = {0};
    strcpy(buf,"2");
    write(sockfd1,buf,100);//向服务器发送2代表要进行登录
    printf("username&passwd> ");
    fflush(stdout);

    memset(buf,0,sizeof(buf));
    gets(buf);
    write(sockfd1,buf,100);//发送要注册的用户名和密码

    read(sockfd1,buf,100);//读取服务器的反馈
printf("%s\n",buf);
    if(0 == strncmp(buf,"ok",2))
    {
        printf("login is ok\n");
        return 1;//返回1便于登录文件服务器判断
    }
else if(0 == strncmp(buf,"no",2))
{
printf("username or passwd is failed\n");
return 0;
}
    return 0;
}

        ------------------------------------------------------------------------------------------------------------------

//修改密码
int update(int sockfd1)
{
    char buf[100] = {0};
    strcpy(buf,"3");
    write(sockfd1,buf,100);//向服务器发送3代表要修改密码
    printf("username&passwd> ");
    fflush(stdout);
    memset(buf,0,sizeof(buf));
    gets(buf);

    write(sockfd1,buf,100);//发送要注册的用户名和密码

    read(sockfd1,buf,100);//读取服务器的反馈
    if(0 == strncmp(buf,"ok",2))
    {
        printf("change is ok\n");
    }
else if(0 == strncmp(buf,"no",2))
{
printf("change is failed\n");
return 0;
}
    return 0;
}

登录验证成功后

网络通信小项目---TCP简单云盘网络通信小项目---TCP简单云盘

和登录数据库服务器一样,将向要进行的操作传递给文件服务器,让它进行相应的操作,并给予反馈。

//上传文件
void up_file(int sockfd,char *buf)

//下载文件
void down_file(int sockfd, char *buf)

//查看服务器上所有文件
void list_file(int sockfd,char *buf)

//查看本地文件
void ls_file(int sockfd,char *buf);


        -----------------------------------------------------------------------------------------------------------------

服务器:

拥有两个并行的服务器数据库服务器和文件服务器,使用多进行实现并发。

用户一连接成功,就进行fork,创建子进程,用来进行用户注册和登录验证处理。

父进程进行用户登录成功后的文件服务器操作,互不影响。

1.数据库服务器

用来进行存储用户名和密码,这里采取了linux下常见的sqlite3数据库进行支撑。

用户连接上数据库服务器后,创建一张存放用户名和密码的表名为user,如果已存在则不创建。

网络通信小项目---TCP简单云盘

用户登录进来后也进行fork创建子进程处理相应的事物,而父进程则负责监听连接下个用户的接入。

//注册后在数据库插入信息
int creat_list(int sqlfd)
{
    sqlite3 *db;
    if(sqlite3_open("my.db",  &db)  !=  SQLITE_OK)
    {
        printf("error : %s\n", sqlite3_errmsg(db));
        exit(-1);
    }

    char sqlbuf[100] = {0};
    char sbuf[10] = {0};
    char cbuf[10] = {0};
    char *errmsg;

    read(sqlfd,sqlbuf,sizeof(sqlbuf));
    myc(sqlbuf,' ',sbuf,cbuf);

    sprintf(sqlbuf,"insert into user values('%s','%s');",sbuf,cbuf);
    if(sqlite3_exec(db, sqlbuf,  NULL,  NULL, &errmsg) !=  SQLITE_OK)
    {
        printf("error :  %s\n",  errmsg);
        char buf[100] = {0};
        strcpy(buf,"no");
write(sqlfd,buf,100);
return 0;
    }
    else
    {
        char buf[100] = {0};
        strcpy(buf,"ok");
        write(sqlfd,buf,100);
        sqlite3_close(db);
    }
}

         ------------------------------------------------------------------------------------------------------------

//验证登录
int login(int sqlfd)
{
    sqlite3 *db;
    //打开或创建数据库
    if(sqlite3_open("my.db",  &db)  !=  SQLITE_OK)
    {
        printf("error : %s\n", sqlite3_errmsg(db));
        exit(-1);
    }

    char sqlbuf[100] = {0};
    char sbuf[10] = {0};
    char cbuf[10] = {0};
    char *errmsg;
char **result;
int a,b;

    read(sqlfd,sqlbuf,sizeof(sqlbuf));
    myc(sqlbuf,' ',sbuf,cbuf);//将读到的用户名和密码分割

    sprintf(sqlbuf,"select * from user where name = '%s' and passwd = '%s';",sbuf,cbuf);
    if(sqlite3_get_table(db, sqlbuf,&result,&a,&b, &errmsg) !=  SQLITE_OK)
    {
        printf("error :  %s\n",  errmsg);
        exit(-1);
    }
    //如果没有找到记录
if(a == 0)
    {
        char buf[100] = {0};
        strcpy(buf,"no");
        write(sqlfd,buf,100);
        sqlite3_close(db);
    }
else//找到记录
{
        char buf[100] = {0};
        strcpy(buf,"ok");
        write(sqlfd,buf,100);
        //sleep(1);
        sqlite3_close(db);
}
}

       -------------------------------------------------------------------------------------------------------------

//修改密码
int change_passwd(int sqlfd)
{
    sqlite3 *db;
    if(sqlite3_open("my.db",  &db)  !=  SQLITE_OK)
    {
        printf("error : %s\n", sqlite3_errmsg(db));
        exit(-1);
    }

    char sqlbuf[100] = {0};
    char sbuf[10] = {0};
    char cbuf[10] = {0};
    char *errmsg;

    read(sqlfd,sqlbuf,sizeof(sqlbuf));
    myc(sqlbuf,' ',sbuf,cbuf);

    sprintf(sqlbuf,"update user set passwd = '%s' where name = '%s';",cbuf,sbuf);
    if(sqlite3_exec(db, sqlbuf,  NULL,  NULL, &errmsg) !=  SQLITE_OK)
{
        printf("error :  %s\n",  errmsg);
        char buf[100] = {0};
        strcpy(buf,"no");
write(sqlfd,buf,100);
return 0;
}
else
{
        char buf[100] = {0};
        strcpy(buf,"ok");
        write(sqlfd,buf,100);
        sqlite3_close(db);

}
}

2.文件服务器:

使得用户能够进行对文件的一系列操作。

用户登录进来同样进行fork创建子进程处理相应的事物,而父进程则负责监听连接下个用户的接入。

//上传文件
                if(0 == strncmp(buf,"up",2))
                {
                          char filename[20] = {0};
                          strcpy(filename,buf+3);
                          read(clientfd,buf,sizeof(buf));
                          int size = atoi(buf);

                          int fd = open(filename,O_CREAT|O_RDWR,0666);
                          while(size)
                          {
                                int n = read(clientfd,buf,sizeof(buf));
                                write(fd,buf,n);
                                size -= n;
                           }
                           close(fd);
                 }

             -------------------------------------------------------------------------------------------------------

//下载文件
                if(0 == strncmp(buf, "down", 4) )
                {
                            char filename[20] = {0};
                            strcpy(filename, buf+5);
                            //send file size
                            struct stat s;
                            stat(filename, &s);
                            sprintf(buf, "%ld", s.st_size);
                            write(clientfd, buf, sizeof buf);
                            //send file data
                            int n;
                            int fd = open(filename, O_RDONLY);
                            while(n = read(fd, buf, sizeof buf))
                                write(clientfd, buf, n);
                            close(fd);
                }

                 
                   

               --------------------------------------------------------------------------------------------------------

//展示服务器上的文件
                if(0 == strncmp(buf,"list",4))
                {
memset(buf,0,sizeof(buf));
int filenum = 0;
                        DIR *dir;
                        struct dirent *dp;
                        dir = opendir(".");
                        while((dp = readdir(dir)) != NULL)
                        {
                                if(dp->d_name[0] == '.')
                                {
                                    continue;
                                }
filenum++;

                        }
sprintf(buf,"%d",filenum);
                        write(clientfd,buf,100);
                        closedir(dir);
                        dir = opendir(".");
                        while((dp = readdir(dir)) != NULL)
                        {
                                if(dp->d_name[0] == '.')
                                {
                                    continue;
                                }
memset(buf,0,sizeof(buf));
strcat(buf,dp->d_name);
write(clientfd,buf,100);
}
closedir(dir);

                }
             
                               
              ------------------------------------------------------------------------------------------------------------

网络通信小项目---TCP简单云盘


网络通信小项目---TCP简单云盘

虽然写的有点low,但是算是一个比较好的入门的小项目,希望大家多多指教,互相交流学习。