项目的原因,我需要搭建一个云服务器,并且利用C/C++上传多个文件至云服务器,网上资料已经非常之多了,站在前辈们的肩膀上确实是事半功倍,我在完成过程中记录了一些很好的blog 和 我自己改进后的程序供大家参考。

  首先,为了能够在你的服务器上运行web项目和访问服务器中的文件,我们需要搭建jdk 和 Apache-tomcat 这两个软件。最好是能找到比较适合的版本,最新版遇到问题后缺乏相应的解决案例。我选用的是apache-tomcat-8.5.61 和 jdk-8u171-linux-x64

  然后,我们需要在tomcat上访问服务器中的内容

  tomcat部署教程

  能够访问文件以后,终于进入正题了!也就是环境交互,由于项目要求,可能会有多次上传的响应,所以这里我写了一个死循环,服务器端会一直等待我上传文件,不会停止,而client端则是有需要再发送指令上传。

  server.cpp:

   #include

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define SERVER_PORT 6666
    #define BUFFER_SIZE 512
    #define SERVER_PATH "/usr/java/tomcat/apache-tomcat-8.5.61/webapps/res/server_text/"
                        //该目录即为上传后的文件需要保存到的路径
    struct sockaddr_in clientAddr;
    int addr_len, serverSocket;
    int init_Server(int port) {
        int serverSocket;
        struct sockaddr_in server_addr;
        //socket初始化
        if((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) d_type==DT_REG)
                cnt++;
        }
        return cnt;
    }
    void receive_File(int client) {
        char recv_buf[BUFFER_SIZE] = {0};
        char filename[200] = {0}, pathname[200] = {0};
        int cnt,n;
        int totalBlock, lenBlock;
        recv(client, recv_buf, sizeof(recv_buf), 0);//先接收客户端要传多少个文件
        int filenum = atoi(recv_buf);
        printf("客户端要发送%d个文件\n",filenum);
        for(int i = 1; i d_type==DT_REG) {
                //printf("%s\n",ptr->d_name);
                strcpy(pre_filename,CLIENT_PATH);
                strcat(pre_filename,ptr->d_name);
                fp = fopen(pre_filename, "rb");
                pack_send_File(clientSocket, fp);
                printf("文件%s上传成功!\n",ptr->d_name);
            }
        }
        return ;
    }
    void sig_up(int sig)
    {
        int clientSocket;
        switch (sig)
        {
            case 37:
                memset(send_buf, 0 , BUFFER_SIZE);
                if((clientSocket  = connect_to_Server((char*)IP_ADDR,SERVER_PORT)) == -1)
                {
                    printf("connect failed!\n");
                    return ;
                }
                printf("connect completed!...\n");
                int filenum = get_File_Num((char*)CLIENT_PATH);
                sprintf(send_buf, "%d\n", filenum);
                send(clientSocket, send_buf, sizeof(send_buf), 0);
                submit_Files(clientSocket);
                sleep(3);
                printf("当前已休眠3s,可进行下一步操作!\n");
            break;
        }
        return ;
    }
    int main() {
        struct sigaction act;
        act.sa_handler = sig_up;
        sigemptyset(&act.sa_mask);
        act.sa_flags = SA_NODEFER; 
        
        sigaction(37, &act, NULL); 
        
        while (1) 
            usleep(100000);
        return 0;
    }

  需要注意的的是:由于项目需求,在client.cpp中,我采用了发送信号的方式进行运行,如果不需要这个功能的话可以将其修改删除。

  第二点就是每次用socket发送完数据包后,要等待一段时间(我测试过10ms和100ms,区别非常大,10ms基本上数据包全部丢失,而100ms则能够将数据包完全的保存下来,保证文件的完整性不被丢失。

  第三点就是用socket发送数据包时,BUFFER_SIZE(每个包的大小)不能定太大也不能定太小,如果到4096,数据包也是很难保存接收,但是传输速度快,而1024就能够很好兼顾接受速度和稳定度,但是测试了几十次之后发现1024也会有丢包的现象,因此我还是选择了更为稳妥的512,在目前测试的近100次中,未出现过一次文件有损失的现象,只是传输速度就会慢一些,但是更加稳妥。

  效果演示:

  首先需要在服务器端运行server文件,监听成功之后再运行client 文件

  在这里插入图片描述

  在这里插入图片描述

  能够看到的是,上传非常成功。

  然后就会面临一个更深层次的问题了:怎么样才能够让服务器一直运行server文件呢?

  这里我用的是screen,也将解决方法推荐给大家(我的代码不需要更改)。

  持续运行文件

  有问题也可也向我发送私信或留言!大家一起进步~

最后修改:2024 年 07 月 27 日
如果觉得我的文章对你有用,请随意赞赏