zoukankan      html  css  js  c++  java
  • Linux网络编程——进程池实现过程详解(3)

    进程池如何提高文件传输效率

    1、协议不变:小火车 服务器端:mmap+memcpy 客户端 recvCycle

    tran_file.c

    #include "function.h"
    
    int tranFile(int newFd){
        Train_t train;
        int ret;
        //发送文件名
        train.dataLen = strlen(FILENAME);
        strcpy(train.buf, FILENAME);
        int fd = open(FILENAME, O_RDONLY);
        ret = send(newFd, &train, 4 + train.dataLen, 0);
        ERROR_CHECK(ret, -1, "send");
        //发文件大小
        struct stat buf;
        fstat(fd, &buf);
        train.dataLen = sizeof(buf.st_size);
        memcpy(train.buf, &buf.st_size, train.dataLen);
        ret = send(newFd, &train, 4 + train.dataLen, 0);
        ERROR_CHECK(ret, -1, "send");
        //发文件内容
        off_t ptrPos = 0;
        char *pMap = (char*)mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
        train.dataLen = 1000;
        //发送1000为内容单位的小火车
        while(ptrPos + 1000 < buf.st_size){
            memcpy(train.buf, pMap + ptrPos, train.dataLen);
            ret = send(newFd, &train, 4 + train.dataLen, 0);
            ERROR_CHECK(ret, -1, "send");
            ptrPos += 1000;
        }
        //发送剩余部分
        train.dataLen = buf.st_size - ptrPos;
        memcpy(train.buf, pMap + ptrPos, train.dataLen);
        ret = send(newFd, &train, 4 + train.dataLen, 0);
        //发送结束标志
        train.dataLen = 0;
        ret = send(newFd, &train, 4, 0);
        ERROR_CHECK(ret, -1, "send");
        munmap(pMap, buf.st_size);
        return 0;
    }
    

    2、协议改变:大火车 服务器端:mmap send 客户端 recvCycle/ mmap

    tran_file.c

    #include "function.h"
    
    int tranFile(int newFd){
        Train_t train;
        int ret;
        //发送文件名
        train.dataLen = strlen(FILENAME);
        strcpy(train.buf, FILENAME);
        int fd = open(FILENAME, O_RDWR);
        ret = send(newFd, &train, 4 + train.dataLen, 0);
        ERROR_CHECK(ret, -1, "send");
        //发文件大小
        struct stat buf;
        fstat(fd, &buf);
        train.dataLen = sizeof(buf.st_size);
        memcpy(train.buf, &buf.st_size, train.dataLen);
        ret = send(newFd, &train, 4 + train.dataLen, 0);
        ERROR_CHECK(ret, -1, "send");
        //发文件内容
        char *pMap = (char*)mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
        ret = send(newFd, pMap, buf.st_size, 0);
        ERROR_CHECK(ret, -1, "send");
        //发送结束标志
        train.dataLen = 0;
        ret = send(newFd, &train, 4, 0);
        ERROR_CHECK(ret, -1, "send");
        munmap(pMap, buf.st_size);
        return 0;
    }
    

    client_reCycle.c

    #include "function.h"
    
    int main(int argc,char* argv[])
    {
    	ARGS_CHECK(argc,3);
    	int socketFd;
    	socketFd=socket(AF_INET,SOCK_STREAM,0);
    	ERROR_CHECK(socketFd,-1,"socket");
    	struct sockaddr_in ser;
    	bzero(&ser,sizeof(ser));
    	ser.sin_family=AF_INET;
    	ser.sin_port=htons(atoi(argv[2]));
    	ser.sin_addr.s_addr=inet_addr(argv[1]);//点分十进制转为32位的网络字节序
    	int ret;
    	ret=connect(socketFd,(struct sockaddr*)&ser,sizeof(ser));
    	ERROR_CHECK(ret,-1,"connect");
    	printf("connect success
    ");
    	int dataLen;
    	char buf[1000]={0};
        //接收文件名
    	recvCycle(socketFd,&dataLen,4);
    	recvCycle(socketFd,buf,dataLen);
    	int fd;
    	fd=open(buf,O_CREAT|O_WRONLY,0666);
    	ERROR_CHECK(fd,-1,"open");
        //接文件大小
        off_t fileSize = 0, oldSize = 0, sliceSize;//文件大小off_t 长整型
    	off_t downLoadSize = 0;
        recvCycle(socketFd,&dataLen,4);
    	recvCycle(socketFd,&fileSize,dataLen);
    	//接受文件内容
        sliceSize = fileSize / 10000;
        dataLen = 1000;
        while(downLoadSize + 1000 < fileSize)
    	{   
            ret = recvCycle(socketFd,buf,dataLen);
            if(-1 == ret){
                printf("
    ");
                printf("server is update!
    ");
                break;
            }
            write(fd, buf, dataLen);
            downLoadSize += dataLen;
            if(downLoadSize - oldSize > sliceSize){
                printf("
    %5.2f%%", (float)downLoadSize / fileSize * 100);
                fflush(stdout);
                oldSize = downLoadSize;
            }
        }
        //剩余部分
        dataLen = fileSize - downLoadSize;
        ret = recvCycle(socketFd, buf, dataLen);
        if(-1 == ret){
            printf("recvCycle last error
    ");
        }
        write(fd, buf, dataLen);
        printf("
    100%%         
    ");
    	close(fd);
    	close(socketFd);
    	return 0;
    }
    

    client_mmap.c

    #include "function.h"
    
    int main(int argc,char* argv[])
    {
        ARGS_CHECK(argc,3);
        int socketFd;
        socketFd=socket(AF_INET,SOCK_STREAM,0);
        ERROR_CHECK(socketFd,-1,"socket");
        struct sockaddr_in ser;
        bzero(&ser,sizeof(ser));
        ser.sin_family=AF_INET;
        ser.sin_port=htons(atoi(argv[2]));
        ser.sin_addr.s_addr=inet_addr(argv[1]);//点分十进制转为32位的网络字节序
        int ret;
        ret=connect(socketFd,(struct sockaddr*)&ser,sizeof(ser));
        ERROR_CHECK(ret,-1,"connect");
        printf("connect success
    ");
        int dataLen;
        char buf[1000]={0};
        //接收文件名
        recvCycle(socketFd,&dataLen,4);
        recvCycle(socketFd,buf,dataLen);
        int fd;
        fd=open(buf,O_CREAT|O_RDWR,0666);
        ERROR_CHECK(fd,-1,"open");
        //接文件大小
        off_t fileSize = 0;//文件大小off_t 长整型
        recvCycle(socketFd,&dataLen,4);
        recvCycle(socketFd,&fileSize,dataLen);
        printf("finish1
    ");
        //接受文件内容
        ftruncate(fd, fileSize); 
        char *pMap = (char*)mmap(NULL, fileSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        ERROR_CHECK(pMap, (char*)-1, "mmap");
        ret = recvCycle(socketFd, pMap, fileSize);
        ERROR_CHECK(ret, -1, "recvCycle");
        printf("finish2
    ");
        ret = recvCycle(socketFd, buf, 4);
        ERROR_CHECK(ret, -1, "recvCycle");
        printf("finish3
    ");
        munmap(pMap, fileSize);
        printf("
    100%%         
    ");
        
        close(fd);
        close(socketFd);
        return 0;
    }
    

    3、协议:大火车 服务器端:sendfile 客户端 mmap

    tran_file.c

    #include "function.h"
    
    int tranFile(int newFd){
        Train_t train;
        int ret;
        //发送文件名
        train.dataLen = strlen(FILENAME);
        strcpy(train.buf, FILENAME);
        int fd = open(FILENAME, O_RDWR);
        ret = send(newFd, &train, 4 + train.dataLen, 0);
        ERROR_CHECK(ret, -1, "send");
        //发文件大小
        struct stat buf;
        fstat(fd, &buf);
        train.dataLen = sizeof(buf.st_size);
        memcpy(train.buf, &buf.st_size, train.dataLen);
        ret = send(newFd, &train, 4 + train.dataLen, 0);
        ERROR_CHECK(ret, -1, "send");
        //发文件内容
        ret = sendfile(newFd, fd, NULL, buf.st_size);
        ERROR_CHECK(ret, -1, "sendfile");
        //发送结束标志
        train.dataLen = 0;
        ret = send(newFd, &train, 4, 0);
        ERROR_CHECK(ret, -1, "send");
        return 0;
    }
    

    4、协议:大火车 服务器端:sendfile 客户端 splice/tee

    client_splice

  • 相关阅读:
    远程获取图片尺寸
    python httplib get和post获取数据
    python 之 logging
    php artisan常用方法
    html页面制作css基本设置
    zlib-1.2.7/libpng-1.5.9 instead of zlib-1.2.8/libpng-1.6.6
    shell脚本自动拉起启动程序
    php截取中文无乱码
    路飞学城1之课程与课程详细
    vuex(数据商店实现思想)day06
  • 原文地址:https://www.cnblogs.com/Mered1th/p/10797315.html
Copyright © 2011-2022 走看看