入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

C++大文件传输

创建时间:2014-05-18 投稿人: 浏览次数:125
C/C++大文件/数据网络传输方法总结

在C/C++网络编程中不免会遇到需要传输大数据、大文件的情况,而由于socket本身缓冲区的限制,大概一次只能发送4K左右的数据,所以在传输大数据时客户端就需要进行分包,在目的地重新组包。而实际上已有一些消息/通讯中间件对此进行了封装,提供了直接发送大数据/文件的接口;除此之外,利用共享目录,ftp,ssh等系统命令来实现大文件/数据也不失为一种好的方法。

1.基础的基于socket进行传输

基础的基于socket进行传输关键在于控制,需要自己行分包和组包。

data-cke-saved-src=http://www.2cto.com/uploadfile/Collfiles/20140117/20140117084908177.jpg

原理很简单那,我们就直接看一下代码吧。

服务器端的编写:

 //////////////////////////////////////////////////////////////////////// 
    // file_server.c -- socket文件传输服务器端示例代码   
    // /////////////////////////////////////////////////////////////////////  
    #include  
    #include  
    #include  
    #include  
    #include  
    #include  
       
    #define HELLO_WORLD_SERVER_PORT    6666 
    #define LENGTH_OF_LISTEN_QUEUE     20 
    #define BUFFER_SIZE                1024 
    #define FILE_NAME_MAX_SIZE         512 
       
    intmain(intargc, char**argv)  
    { 
        // set socket"s address information   
        // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口  
        struct sockaddr_in   server_addr;  
        bzero(&server_addr, sizeof(server_addr));  
        server_addr.sin_family = AF_INET;  
        server_addr.sin_addr.s_addr = htons(INADDR_ANY);  
        server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);  
       
        // create a stream socket   
        // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口  
        intserver_socket = socket(PF_INET, SOCK_STREAM, 0); 
        if(server_socket < 0) 
        { 
            printf(Create Socket Failed!
); 
            exit(1); 
        } 
       
        // 把socket和socket地址结构绑定   
        if(bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))  
        { 
            printf(Server Bind Port: %d Failed!
, HELLO_WORLD_SERVER_PORT);  
            exit(1); 
        } 
       
        // server_socket用于监听   
        if(listen(server_socket, LENGTH_OF_LISTEN_QUEUE))  
        { 
            printf(Server Listen Failed!
); 
            exit(1); 
        } 
       
        // 服务器端一直运行用以持续为客户端提供服务   
        while(1) 
        { 
            // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept  
            // 接受此请求,同时将client端的地址和端口等信息写入client_addr中  
            struct sockaddr_in client_addr;  
            socklen_t          length = sizeof(client_addr);  
       
            // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中  
            // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以  
            // 用select()来实现超时检测   
            // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信  
            // 这里的new_server_socket代表了这个通信通道  
            intnew_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length); 
            if(new_server_socket < 0) 
            { 
                printf(Server Accept Failed!
); 
                break; 
            } 
       
            charbuffer[BUFFER_SIZE];  
            bzero(buffer, sizeof(buffer));  
            length = recv(new_server_socket, buffer, BUFFER_SIZE, 0); 
            if(length < 0) 
            { 
                printf(Server Recieve Data Failed!
); 
                break; 
            } 
       
            charfile_name[FILE_NAME_MAX_SIZE + 1]; 
            bzero(file_name, sizeof(file_name));  
            strncpy(file_name, buffer,  
                    strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));  
       
            FILE *fp = fopen(file_name, r);  
            if(fp == NULL)  
            { 
                printf(File:    %s Not Found!
, file_name);  
            } 
            else 
            { 
                bzero(buffer, BUFFER_SIZE);  
                intfile_block_length = 0; 
                while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0) 
                { 
                    printf(file_block_length = %d
, file_block_length);  
       
                    // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端  
                    if(send(new_server_socket, buffer, file_block_length, 0) < 0) 
                    { 
                        printf(Send File:   %s Failed!
, file_name);  
                        break; 
                    } 
       
                    bzero(buffer, sizeof(buffer));  
                } 
                fclose(fp); 
                printf(File:    %s Transfer Finished!
, file_name);  
            } 
       
            close(new_server_socket); 
        } 
       
        close(server_socket); 
       
        return0; 
    }  
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。