Linux系统下C语言实现百度网盘(附实现步骤,和全部代码讲解)

Linux操作系统下用C语言写一个网盘

本次实验完成了完整的网盘功能(查询文件,下载文件,上传文件,刷新界面,和退出系统),包括附加功能查询特定目录下的文件进行下载或者上传)。

  • 初始文件分配,在根目录下的初始文件是dd.txt ee.txt 而./download里面的文件是a.txt b.txt c.txt.。 分别用于客户下载和客户上传文件。

在这里插入图片描述
在这里插入图片描述

  • 刷新网盘的界面: 当用户输入4,重新输入网盘的可视化界面,并且让用户选择执行的操作。

在这里插入图片描述

void net_disk_ui()   //网盘可视化页面
{
    
    
    printf("======================TCP网盘客户端==================\n");
    printf("=========================功能菜单====================\n");
    printf("\t\t\t1.查询文件\n");
    printf("\t\t\t2.下载文件\n");
    printf("\t\t\t3.上传文件\n");
    printf("\t\t\t4.刷新界面\n");
    printf("\t\t\t0.退出系统\n");
    printf("------------------------------------------------------\n");
    printf("请选择你要执行的操作: \n");
}
case '4':
{
    
    
    net_disk_ui();
}
  • 查询文件: 当用户输入1,输出home/drj/目录下的文件列表

在这里插入图片描述

case '1':   //  要让服务器给我们发送目录信息->客户端也要创捷线程
    // 这个while循环本身也是死循环,我们要让客户端也创建线程,让接受服务器的数据的代码放进线程中
    send_msg.type = MSG_TYPE_FILENAME;
    res = write(client_socket, &send_msg, sizeof(MSG));
    if (res < 0)
    {
    
    
        perror("send msg error: ");
    }
    memset(&send_msg, 0, sizeof(MSG));
    break;
  • 下载文件: 根据给定被下载文件的路径以及需要下载的指定位置,连续下载两个文件,并且下载路径和内容无误
    • 当用户输入2的时候,先显示当前目录/home/drj目录下有哪些内容,让用户进行选择下载哪一个文件
    • 经过下载,./download目录下由dd.txt 和 ee.txt这两个文件,并且核对文件内容无误,下载成功操作。

在这里插入图片描述

// 客户端
case '2':
{
    
    
    send_msg.type = MSG_TYPE_DONWLOAD;
    struct dirent* dir = NULL;
    printf("there are  files in /home/drj : \n");
    DIR* dp = opendir("/home/drj");
    while (1)
    {
    
    
        dir = readdir(dp);
        if (NULL == dir)
        {
    
    
            break;
        }
        if (dir->d_name[0] != '.')
            printf("%s  ", dir->d_name);
    }
    printf("\ninput download filename: \n");
    scanf("%s", down_file_name);
    strcpy(send_msg.fname, down_file_name);
    res = write(client_socket, &send_msg, sizeof(MSG));
    if (res < 0)
    {
    
    
        perror("send msg error: ");
    }
    memset(&send_msg, 0, sizeof(MSG));
    break;
}
// 服务器
else if (recv_msg.type == MSG_TYPE_DONWLOAD)
{
    
    
    strcpy(down_file_name, recv_msg.fname);
    printf("要下载的文件是%s\n", down_file_name);
    server_file_download(acpt_socket);
    memset(&recv_msg, 0, sizeof(MSG));
}
  • 上传文件: 将download下文件a.txt b.txt c.txt上入 /home/drj目录下,传递完成,服务器和客户端都没有错误,并且上传的字节数和内容无误。
    • 输入3 ,给用户展示当前文件夹先有的文件,并且让用户选择一个进行上传。给出上传文件的路径以及当前文件的大小。
    • 连续上传三个文件,然后在根目录下检查文件是否上传成功,以及文章内容是否正确等。可以看到,三个文件全部上传成功并且文件内容全部正确。

在这里插入图片描述

// 客户端
case '3': {
    
            
    send_msg.type = MSG_TYPE_UPLOAD;
    struct dirent* dir = NULL;
    printf("there are  files in ./download  : \n");
    DIR* dp = opendir("./download");
    while (1)
    {
    
    
        dir = readdir(dp);
        if (NULL == dir)
        {
    
    
            break;
        }
        if (dir->d_name[0] != '.')
            printf("%s  ", dir->d_name);
    }
    printf("\ninput upload filename: \n");
    scanf("%s", up_file_name);
    // 发送一个数据包告诉服务器,准备上传文件了
    strcpy(send_msg.fname, up_file_name);
    // f发送数据给服务器
    res = write(client_socket, &send_msg, sizeof(MSG));
    if (res < 0)
    {
    
    
        perror("send upload packege error");
        continue; //不走下面了
    }
    memset(&send_msg, 0, sizeof(MSG));
    // 由于考虑到上传文件是需要时间的,如果文件很大,那么就需要非常长的时间
    // 如果这个时候写在这里会导致其他功能卡住,因此需要把发送文件内容的代码放进线程里面,因此需要创建线程
    // 因此我们客户都拿还需要创建一个新的线程,专门处理文件的上传任务;
    pthread_create(&pthread_send_id, NULL, upload_file_thread, &client_socket); //创建一个线程
    break;
}

// 服务器
else if (recv_msg.type == MSG_TYPE_UPLOAD)  //如果收到的是上传包,说明准备接受客户端发来的文件数据
{
    
    
    printf("进入upload\n");

    //从数据包的文件名获取文件名信息并创建文件,默认创建的文件夹在家目录下
    strcpy(up_file_name, recv_msg.fname);

    char path[20] = "/home/drj/";
    strcat(path, up_file_name);
    printf("当前要下载到的文件位置是 %s \n", path);
    // 创建文件,在家目录下,下需要定义文件名描述符
    fd = open(path, O_CREAT | O_WRONLY, 0666);
    if (fd < 0)
    {
    
    
        perror("create up file error");
    }
}
else if (recv_msg.type == MSG_TYPE_UPLOAD_DATA)
{
    
    
    // 写的字节数是recv_msg.bytes
    printf("文件开始开始上传\n");
    res = write(fd, recv_msg.buffer, recv_msg.bytes);
    
    if (recv_msg.bytes < sizeof(recv_msg.buffer))
    {
    
    
        //说明是最后一个包,这部分数据是文件的最后数据了
        printf("client up file ok\n");
        close(fd);
    }
    memset(&recv_msg, 0, sizeof(MSG));
}

完整代码:

服务器

#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

char down_file_name[20] = {
    
     0 };
#define MSG_TYPE_LOGIN 0
#define MSG_TYPE_FILENAME 1
#define MSG_TYPE_DONWLOAD 2
#define MSG_TYPE_UPLOAD 3
#define MSG_TYPE_UPLOAD_DATA 4

typedef struct msg
{
    
    
    int type; // 协议类型  0 表示登录协议,1表示文件传输包 2 表示文件下载
    int flag; 
    char buffer[1024];  //存放除文件名之外的内容
    char fname[50];  //如果type是1 就是文件名传输包,这个结构体会添加新的字段;
    int bytes;   // 这个字段用来记录传输文件时候每个数据包实际的文件数
}MSG;//这个结构体会根据业务需求的不断变化,会添加新的字段。


void search_server_dir(int accept_socket)
// 通过打开服务器中的某个文件,并使用  socket 网络发送给客户端  至于什么文件我们先顶一个。。。e
//可以根据实际情况定义
{
    
    
    struct dirent * dir = NULL;   //定义目录的结构体;
    MSG info_msg = {
    
     0 };
    int res = 0;
    //opendir 是打开Linux目录的api函数
    DIR* dp = opendir("/home/drj");
    info_msg.type = MSG_TYPE_FILENAME;
    if (NULL == dp)
    {
    
    
        perror("open dir error: ");
        return;
    }
    while (1)
    {
    
    
        dir = readdir(dp);
        if (NULL == dir) //目录遍历完成,函数返回空值,表示目录全部读取完成
        {
    
    
            break;
        }
        if (dir->d_name[0] != '.') //过滤掉.隐藏文屏蔽 
        {
    
    
            printf("name = %s\n", dir->d_name);
            memset(info_msg.fname, 0, sizeof(info_msg.fname));
            strcpy(info_msg.fname, dir->d_name);
            res = write(accept_socket, &info_msg, sizeof(MSG)); //把每个文件名拷贝到
            // info_msg结构体中,通过该套接字发送出去。
            if (res < 0)
            {
    
    
                perror("send client error: ");
                return;
            }
        }
    }
}

void server_file_download(int accept_socket)
{
    
    
    MSG  file_msg = {
    
     0 };
    int res = 0;
    int fd;   //文件描述符  linux系统下很重要的概念,linux认为所有设备都是文件描述符。对文件的 打开对设备。
    // 都可以使用文件描述符概念。
    char path[20] = "/home/drj/";
    strcat(path, down_file_name);
    fd = open(path, O_RDONLY);

    if (fd < 0)
    {
    
    
        perror("file open error: ");
        return;
    }
    // 在读取文件并把文件传到客户端,这个时候msg结构体中的buffer 就是存放文件的内容,
    // 但是一般来说文件都超过1024,所以要发送多个包;
    file_msg.type = MSG_TYPE_DONWLOAD;
    strcpy(file_msg.fname, "ee.txt");

    while ((res = read(fd, file_msg.buffer, sizeof(file_msg.buffer))) > 0)
        // read用于读取文件的时候,当文件读到末尾的时  
        // res是实际读到的字节
    {
    
    
        file_msg.bytes = res;
        res = write(accept_socket, &file_msg, sizeof(MSG));
        if (res <= 0)
        {
    
    
            perror("server send file error: ");
        }
        memset(file_msg.buffer, 0, sizeof(file_msg.buffer));
    }

}

void* thread_fun(void* arg)
{
    
    
    int acpt_socket = *((int*)arg);
    int res;
    char buffer[50] = {
    
     0 };
    char up_file_name[20] = {
    
     0 };
    MSG recv_msg = {
    
     0 };
    int fd = -1;  //定义一个打开文件的描述符
    //read函数就是接受客户端发来的数据,返回实际从客户端那边收到的字节数。
    //buffer: 收到客户端数据后把数据存放的地址  sizeof(buffer) 就是希望读取的字节数
    //search_server_dir(acpt_socket);
    printf("目录发送客户端完成!\n");
    while (1)
    {
    
    
        // todo  #################################sizeof(recv_msg)
        res = read(acpt_socket, &recv_msg, sizeof(recv_msg));
        if (res == 0)  //说明客户端已经断开,read默认情况下他是堵塞模式,回答问题才能说出下一句话
        {
    
    
            printf("客户端已经断开");
            break;    // 线程结束
        }
        if (recv_msg.type == MSG_TYPE_FILENAME) //说明客户端发过来的是目录
        {
    
    
            search_server_dir(acpt_socket);
            memset(&recv_msg, 0, sizeof(MSG));
        }
        else if (recv_msg.type == MSG_TYPE_DONWLOAD)
        {
    
    
            strcpy(down_file_name, recv_msg.fname);
            printf("要下载的文件是%s\n", down_file_name);
            server_file_download(acpt_socket);
            memset(&recv_msg, 0, sizeof(MSG));
        }
        else if (recv_msg.type == MSG_TYPE_UPLOAD)  //如果收到的是上传包,说明准备接受客户端发来的文件数据
        {
    
    
            printf("进入upload\n");

            //从数据包的文件名获取文件名信息并创建文件,默认创建的文件夹在家目录下
            strcpy(up_file_name, recv_msg.fname);

            char path[20] = "/home/drj/";
            strcat(path, up_file_name);
            printf("当前要下载到的文件位置是 %s \n", path);
            // 创建文件,在家目录下,下需要定义文件名描述符
            fd = open(path, O_CREAT | O_WRONLY, 0666);
            if (fd < 0)
            {
    
    
                perror("create up file error");
            }
        }
        else if (recv_msg.type == MSG_TYPE_UPLOAD_DATA)
        {
    
    
            // 写的字节数是recv_msg.bytes
            printf("文件开始开始上传\n");
            res = write(fd, recv_msg.buffer, recv_msg.bytes);
            
            if (recv_msg.bytes < sizeof(recv_msg.buffer))
            {
    
    
                //说明是最后一个包,这部分数据是文件的最后数据了
                printf("client up file ok\n");
                close(fd);
            }
            memset(&recv_msg, 0, sizeof(MSG));
        }
        // printf("client read %s\n", buffer);
        // write(acpt_socket, buffer, res);
         memset(&recv_msg, 0, sizeof(MSG));
        //服务器收到客户端数据后,原封不动的发给客户端
    }
}
int main()
{
    
    
    char buffer[50] = {
    
     0 };
    int res = 0;
    int server_socket; //这个是socket网络描述符,也叫套接字描述符。
    int accept_socket;
    // 第一步:创建套接字描述符       --“买一部手机”
    pthread_t thread_id; //线程编号

    
    printf("开始创建tcp服务器\n");
    server_socket = socket(AF_INET, SOCK_STREAM, 0);//我们想要向网络发送数据都使用
    //server_socket这个套接字描述符

    if (server_socket < 0)
    {
    
    
        perror("socket create failed:");
        return 0;
    }

    // 第二步:要告诉这个服务器 我的ip地址和端口号 我们要有一个保存ip地址和端口的变量
                //          --“买电话卡”
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET; // 表示ipv4地址协议
    server_addr.sin_addr.s_addr = INADDR_ANY;   //inaddr_any 存服务器ip地址,告诉系统自动绑定网卡ip地址
    server_addr.sin_port = htons(1046);    //网络地址转换,把主机字节顺序转换成网络字节顺序
    // 端口号1024以上即可。
    // 
    // 
    // 如果服务器程序退出之后,又立刻打开服务器,系统会提示地址已经被使用
    //这是因为ip地址和端口号是系统资源,必须设置为端口号为重复使用。
    int optvalue = 1;
    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &optvalue, sizeof(optvalue));
    // 第三步:把我们设定好的ip地址和端口号绑定到我们的server_socket描述符上。 --“把电话卡插入手机上”

    if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
    {
    
    
        perror("server bind error:");
        return 0;
    }

    // 第四步:我们调用listen 开始监听程序    --“把电话放在身上,电话铃响听到声音”
    if (listen(server_socket, 10) < 0)
    {
    
    
        perror("server listen error:");
        return 0;
    }

    // 第五步:以上4个步骤都ok后,我们就可以等待客户端连接过来了。

    // accept 函数有一个特点,当我们程序调用这个函数的时候,如果没有客户端连接到我们的服务器,
    // 那么这个函数将堵塞(程序停下不走了),直到有客户端连接到服务器,这个函数将解开,并
    // 并且返回一个新的套接字描述符。那么后期和客户端的通讯都交给这个新的套接字描述符来负责。
    printf("TCP服务器准备完成,等待客户端连接!\n");
    
    while (1)
    {
    
    
        accept_socket = accept(server_socket, NULL, NULL);
		printf("有客户端连接到服务器!\n");
        //创建一个新的线程,创建成功之后,系统就会执行‘thread_fun’代码,这里就是多线程代码。
        pthread_create(&thread_id, NULL, thread_fun, &accept_socket);   // 第三个参数  函数指针 真正执行函数的指针
        // 移动到最前面函数里面去了。
    }

    printf("%s 向你问好!\n", "LINUX_C_SAMPLE");
    return 0;
}

客户端

#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>

// 编写客户端
#define MSG_TYPE_LOGIN 0
#define MSG_TYPE_FILENAME 1
#define MSG_TYPE_DONWLOAD 2
#define MSG_TYPE_UPLOAD 3
#define MSG_TYPE_UPLOAD_DATA 4
char down_file_name[20] = {
    
     0 };
char up_file_name[20] = {
    
     0 };
typedef struct msg
{
    
    
    int type; // 协议类型  0 表示登录协议,1表示文件传输包
    int flag;
    char buffer[1024]; //存放除文件名之外的内容
    char fname[50]; //如果type是1 就是文件名传输包,这个结构体会添加新的字段;
    int bytes; // 这个字段用来记录传输文件时候每个数据包实际的文件数
}MSG;//这个结构体会根据业务需求的不断变化,会添加新的字段。
  // 全局变量  用来打开文件进行读写的文件描述符,默认情况下为0
int fd = -1;//进行读写的文件标识符
void net_disk_ui()
{
    
    
    printf("======================TCP网盘客户端==================\n");
    printf("=========================功能菜单====================\n");
    printf("\t\t\t1.查询文件\n");
    printf("\t\t\t2.下载文件\n");
    printf("\t\t\t3.上传文件\n");
    printf("\t\t\t4.刷新界面\n");
    printf("\t\t\t0.退出系统\n");
    printf("------------------------------------------------------\n");
    printf("请选择你要执行的操作: \n");

}
// 根据网盘客户端业务需求,客户端想要查看下服务器这边目录下的文件信息。因此
// 服务器必须设计一个功能,把某个目录下的文件名信息全部获取出来发给客户端。
// 默认情况下服务器的目录,用户的目录设置为家home目录
// 在Linux下如何对文件和目录进行读取并获取文件名


void * thread_func(void* arg)
{
    
    
    int client_socket = *((int*)arg);
    MSG recv_msg = {
    
     0 };
    int res;
    char pwd[100] = {
    
     0 } ;
    while (1)
    {
    
    
        //用来接受服务器发过来的数据
        res = read(client_socket, &recv_msg, sizeof(MSG));
        if (recv_msg.type == MSG_TYPE_FILENAME)
        {
    
    
            printf("server path filename=%s\n", recv_msg.fname);
            memset(&recv_msg, 0, sizeof(MSG));
        }
        else if (recv_msg.type == MSG_TYPE_DONWLOAD)  // 做好接受准备,一定是一个文件
        {
    
    

            // 1.创建一个目录
            if (mkdir("download", S_IRWXU) <0 )
            {
    
    
                if (errno == EEXIST)
                {
    
    
                    printf("download dir exist continue!!\n");
                }
                else
                {
    
    
                    perror("mkdir error: ");
                }
            }
            // 目录创建没有问题,就要开始创建文件了。
            if (fd == -1)  //表示文件还没打开过,若非0 已经打开过了
            {
    
    
                //printf("\ncurrent = %s\n", getcwd(NULL,0));
                char path[20] = "./download/";
                strcat(path, down_file_name);
                printf("download path = %s\n", path);
                fd = open(path, O_CREAT | O_WRONLY, 0666); //打开过肯定会有个文件描述返回  0666读写可执行
                if (fd < 0)
                {
    
    
                    perror("file open error: ");
                }

            }
            // 通过上面的创建目录以及文件描述的判断,通过后就可以从MSG结构体里面的buffer取数据了。
            // recv_msg.buffer  存放的就是文件的部分内容。 recv_msg.bytes就这个部分文件的字节。
            res = write(fd, recv_msg.buffer, recv_msg.bytes);
            if (res < 0)
            {
    
    
                perror("file write error : ");
            }
            // 那么我们判断文件的内容都全部发完了吗?通过recv_msg.bytes 如果小于recv_buffer的1024 
            if (recv_msg.bytes < sizeof(recv_msg.buffer))
            {
    
    
                printf("file download finish!!\n");
                close(fd);
                fd = -1;
            }
        }

    }
}

void* upload_file_thread(void * args)
{
    
    
    // 客户端实现上传文件到服务器逻辑
    // 1.打开文件 
    MSG up_file_msg = {
    
     0 };
    int client_socket = *((int*)args);
    int fd = -1;
    int res = 0;  //实际读入的文件名
    char buffer[1024] = {
    
     0 }; //用来保存读取文件的缓冲区数据


    char path[20] = "./download/";
    strcat(path, up_file_name);
    printf("客户端上传文件的路径是%s \n", path);
    fd = open(path, O_RDONLY);
    if (fd < 0)
    {
    
    
        perror("client  open up file error:");
        return NULL;
    }
    up_file_msg.type = MSG_TYPE_UPLOAD_DATA;
    //2.读取文件
    while ((res = read(fd, buffer, sizeof(buffer)) )> 0)
    {
    
    
        // 要把文件数据拷贝到MSG结构体中的buffer中
        printf("传入的字节数目:%d 字节\n", res);
        memcpy(up_file_msg.buffer, buffer, res);
        up_file_msg.bytes = res;
        res = write(client_socket, &up_file_msg, sizeof(MSG));//写的字节数一定是读的总数据
        memset(buffer, 0, sizeof(buffer));
        memset(up_file_msg.buffer, 0, sizeof(up_file_msg.buffer));
    }
}


int main()
{
    
    
    int client_socket;
    //todo 定义
    pthread_t  pthread_id;  //线程编号
    pthread_t  pthread_send_id;
    char c;
    struct sockaddr_in server_addr; //用来连接到服务器的ip地址和端口号
    char buffer[50] = {
    
     0 };
    client_socket = socket(AF_INET,SOCK_STREAM,0);
    int res;
    MSG recv_msg = {
    
     0 };
    MSG send_msg = {
    
     0 };
    if (client_socket < 0)
    {
    
    
        perror("client socket faile: ");
        return 0;
    }
    server_addr.sin_family = AF_INET; //ipv协议 且自动匹配绑定 
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    // 两种方法如果服务器和客户端都在同一台电脑中,ip地址可以设置为127.0.0.1
    // 现在就是服务器和客户端中在同一个机子上,因此可以127.0.0.1.
    server_addr.sin_port = htons(1046);
    printf("这是客户端\n");
    // 创建好套接字之后,客户端要连接到服务器,使用conect()函数

    if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
    {
    
    
        perror("connect error:  ");
        return 0;
    }
    printf("客户端连接服务器成功\n");
    
    pthread_create(&pthread_id, NULL, thread_func, &client_socket);
    net_disk_ui();
    // 我们用户在客户端中连续输入字符,回车表示把数据发出去,把buffer里的数据发出去;服务器有固定ip地址即可,不一定在一个主机上
    while (1)
    {
    
    
        c = getchar();
        switch (c)
        {
    
    
        case '1':   //  要让服务器给我们发送目录信息->客户端也要创捷线程
            // 这个while循环本身也是死循环,我们要让客户端也创建线程,让接受服务器的数据的代码放进线程中
            send_msg.type = MSG_TYPE_FILENAME;
            res = write(client_socket, &send_msg, sizeof(MSG));
            if (res < 0)
            {
    
    
                perror("send msg error: ");
            }
            memset(&send_msg, 0, sizeof(MSG));
            break;
        case '2':
        {
    
    
            send_msg.type = MSG_TYPE_DONWLOAD;
            struct dirent* dir = NULL;
            printf("there are  files in /home/drj : \n");
            DIR* dp = opendir("/home/drj");
            while (1)
            {
    
    
                dir = readdir(dp);
                if (NULL == dir)
                {
    
    
                    break;
                }
                if (dir->d_name[0] != '.')
                    printf("%s  ", dir->d_name);
            }
            printf("\ninput download filename: \n");
            scanf("%s", down_file_name);
            strcpy(send_msg.fname, down_file_name);
            res = write(client_socket, &send_msg, sizeof(MSG));
            if (res < 0)
            {
    
    
                perror("send msg error: ");
            }
            memset(&send_msg, 0, sizeof(MSG));
            break;
        }
        case '3': {
    
            
            send_msg.type = MSG_TYPE_UPLOAD;
            struct dirent* dir = NULL;
            printf("there are  files in ./download  : \n");
            DIR* dp = opendir("./download");
            while (1)
            {
    
    
                dir = readdir(dp);
                if (NULL == dir)
                {
    
    
                    break;
                }
                if (dir->d_name[0] != '.')
                    printf("%s  ", dir->d_name);
            }
            printf("\ninput upload filename: \n");
            scanf("%s", up_file_name);
            // 发送一个数据包告诉服务器,准备上传文件了
            strcpy(send_msg.fname, up_file_name);
            // f发送数据给服务器
            res = write(client_socket, &send_msg, sizeof(MSG));
            if (res < 0)
            {
    
    
                perror("send upload packege error");
                continue; //不走下面了
            }
            memset(&send_msg, 0, sizeof(MSG));
            // 由于考虑到上传文件是需要时间的,如果文件很大,那么就需要非常长的时间
            // 如果这个时候写在这里会导致其他功能卡住,因此需要把发送文件内容的代码放进线程里面,因此需要创建线程
            // 因此我们客户都拿还需要创建一个新的线程,专门处理文件的上传任务;
            pthread_create(&pthread_send_id, NULL, upload_file_thread, &client_socket); //创建一个线程
            break;
        }
        case '4':
        {
    
    
            net_disk_ui();
        }
        }
    }
    /*
    while (1)
    {
 
        res = read(client_socket, &recv_msg, sizeof(MSG));


        if (recv_msg.type == MSG_TYPE_FILENAME)
        {
            printf("server path filename = %s\n", recv_msg.fname);
            memset(&recv_msg, 0, sizeof(MSG));
        }
        
    }
    */


    /*
    //用户在客户端中连续输入字符,回车发送数据
    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
    {
        res = write(client_socket, buffer, sizeof(buffer));
        printf("send bytes =%d\n", res);
        memset(buffer, 0, sizeof(buffer));

        res = read(client_socket, buffer, sizeof(buffer));
        printf("recv from server info : % s\n", buffer);
        memset(buffer, 0, sizeof(buffer));
    }
    */


    printf("%s 向你问好!\n", "linux_02");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_63669388/article/details/133491678