首页 > 系统相关 >利用进程池给客户端传文件

利用进程池给客户端传文件

时间:2024-06-04 23:35:01浏览次数:11  
标签:include int len msg fd 进程 池给 cmsg 客户端

主函数

#include <func.h>
#include "process_pool.h"
#include "server.h"
#include "transferFd.h"
#define EVENTSNUM 100

int main(int argc,char* argv[]){
    //ip port processNum
    if(argc != 4){
        error(1,errno,"need three arguments");
    }

    char* ip = argv[1];
    int port = atoi(argv[2]);
    int processNum = atoi(argv[3]);
    process_pool* pProcess = (process_pool*)calloc(processNum,sizeof(process_pool));

    makeChildren(pProcess,processNum);

    int listenfd = serverCreate(ip,port);
    if(listenfd == -1){
        perror("serverCreate");
    }

    int epfd = epoll_create1(0);
    listenAdd(epfd,listenfd);
    for(int i = 0;i < processNum;i++){
        listenAdd(epfd,pProcess[i].peerfd);
    }
    struct epoll_event events[EVENTSNUM]; 

    while(1){
        int nReady = epoll_wait(epfd,events,EVENTSNUM,-1);

        for(int i = 0;i < nReady;i++){
            int fd = events[i].data.fd;

            if(fd == listenfd){
                int peerfd = accept(listenfd,NULL,NULL);
                if(peerfd == -1){
                    perror("accept");
                }
                printf("connection\n");
                for(int j = 0;j < processNum;j++){
                    if(pProcess[j].processStatus == FREE){
                         sendFd(pProcess[j].peerfd,peerfd);
                         pProcess[j].processStatus = BUSY;
                         break;
                    }
                }
                close(peerfd);
            }else{
                char buffer[1024];
                memset(buffer,0,sizeof(buffer));
                read(fd,buffer,sizeof(buffer));
                for(int j = 0;j < processNum;j++){
                    if(pProcess[j].peerfd == fd){
                            pProcess[j].processStatus = FREE;
                            break;
                    }
                }

            }
        }
    }
    close(listenfd);
    return 0;
}

process_pool

#include <func.h>
#include "process_pool.h"
#include <sys/uio.h>
#include "transferFd.h"
#include "server.h"

int handleTask(int pipeFd){
    printf("child handle task\n");
    while(1){
        int clientFd;
        char fileName[] = "hello.txt";
        recvFd(pipeFd,&clientFd);

        printf("clientFd : %d\n",clientFd);
        sendFile(clientFd,fileName);
        close(clientFd);
        int OK = 1;
        write(pipeFd,&OK,sizeof(OK));
    }
    
    return 0;
}



int makeChildren(process_pool* pProcess,int processNum){
    printf("processNum : %d\n",processNum);
    for(int i = 0;i < processNum;i++){
        
        int pipe[2];
        socketpair(AF_LOCAL,SOCK_STREAM,0,pipe);
        pid_t pid = fork();
        if(pid == 0){
            close(pipe[1]);
            handleTask(pipe[0]);
            exit(0);
        }
        close(pipe[0]);
        printf("chile %d\n",pid);
        pProcess[i].pid = pid;
        pProcess[i].processStatus = FREE;
        pProcess[i].peerfd = pipe[1];
        
    }
    return 0;
}

server

#include "server.h"
#include <func.h>
int serverCreate(char*ip,int port){
    int sfd = socket(AF_INET,SOCK_STREAM,0);
    if(sfd == -1){
        perror("socket");
    }

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr(ip);
    serverAddr.sin_port = htons(port);
    int on = 1;
    setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

    int ret = bind(sfd,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
    if(ret == -1){
        perror("bind");
    }
    ret = listen(sfd,10);
    if(ret == -1){
        perror("listen");
    }
    return sfd;
}

int listenAdd(int epfd,int fd){
    struct epoll_event ev;
    ev.data.fd = fd;
    ev.events = EPOLLIN;
    int ret = epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);
    if(ret == -1){
        perror("epoll_ctl");
    }
    return 0;
}

int listenDel(int epfd,int fd){
    int ret = epoll_ctl(epfd,EPOLL_CTL_DEL,fd,NULL);
    if(ret == -1){
        perror("epoll_ctl");
    }
    return 0;
}

int sendFile(int clientFd,char* fileName){
    fileInfo file;
    file.len = strlen(fileName);

    strcpy(file.fileContent,fileName);    
    send(clientFd,&file,4 + file.len,0);
    printf("fileName: %s\n",file.fileContent);

    int fd = open(fileName,O_RDONLY);
    struct stat buf;
    int ret = fstat(fd,&buf);
    if(ret == -1){
        error(1,errno,"fstat");
    }


    file.len = buf.st_size;
    char buffer[100];
    read(fd,buffer,sizeof(buffer));
    strncpy(file.fileContent,buffer,file.len);
    send(clientFd,&file,4 + file.len,0);

    printf("fileContent: %s\n",file.fileContent);
    return 0;
}

transferFd

#include <func.h>
#include <sys/uio.h>
#include "transferFd.h"

int sendFd(int pipeFd,int fd){
     
    int len = CMSG_LEN(sizeof(fd));
    struct cmsghdr* cmsg = (struct cmsghdr*)calloc(1,len);
    cmsg->cmsg_len = len;
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    int *p = (int*)CMSG_DATA(cmsg);
    *p = fd;
    char buff[4] = {0};
    //构建第二组成员
    struct iovec iov;
    iov.iov_base = buff;
    iov.iov_len = sizeof(buff);

    struct msghdr msg;
    msg.msg_control = cmsg;
    msg.msg_controllen = len;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    sendmsg(pipeFd,&msg,0);
    printf("sendFd sucess\n");
    free(cmsg);
    return 0;
}

int recvFd(int pipeFd,int* pfd){

    int len = CMSG_LEN(sizeof(int));
    struct cmsghdr* cmsg = (struct cmsghdr*)calloc(1,len);
    cmsg->cmsg_len = len;
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;

    char buff[4] = {0};
    //构建第二组成员
    struct iovec iov;
    iov.iov_base = buff;
    iov.iov_len = sizeof(buff);

    struct msghdr msg;
    msg.msg_control = cmsg;
    msg.msg_controllen = len;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    recvmsg(pipeFd,&msg,0);
    printf("recv success\n");
    *pfd = *(int*)CMSG_DATA(cmsg);
    free(cmsg);
    return 0;
}

标签:include,int,len,msg,fd,进程,池给,cmsg,客户端
From: https://www.cnblogs.com/EavenWang/p/18231996

相关文章

  • IO进程线程(五)库的制作、进程
    文章目录一、库(一)静态库1.概念2.制作3.使用(编译)(1)生成可执行文件(2)运行(二)动态库(共享库)1.概念2.制作3.生成可执行文件4.基于动态库的可执行文件的执行过程二、进程(一)概念1.进程2.进程和程序的区别3.进程的组成4.进程的种类(1)交互进程(2)批处理进程(3)守护进程5.......
  • 进程间的通信(管道)
    进程间的通信(管道)进程间的通信(Inter-ProcessCommunication,IPC)是指在不同进程之间传递或交换信息。这些进程可以是运行在同一台计算机上,也可以是通过网络连接的不同计算机上的。由于不同的进程拥有不同的内存空间,因此不能通过简单地直接访问对方的内存空间来实现信息的传递或共......
  • 09-进程和计划任务管理
    9.1查看和控制进程9.1.1查看进程1.ps命令pS命令是Linux操作系统中最为常用的进程查看工具,主要用于显示包含当前运行的各进程完整信息的静态快照。通过不同的命令选项,可以有选择性地查看进程信息。命令作用a显示当前终端下的所有进程信息,包括其他用户的进程。u......
  • Linux学习笔记6 进程角度看内存泄露
    一,从进程角度看堆区内存申请与释放问题1,c语言中的内存泄漏内存溢出:申请内存时,没用足够的内存可以使用。 内存泄露:严格来说,只有对象不会再被程序用到了,但是GC又不能回收它们的情况,才叫内存泄漏                宽泛的讲,实际情况中很多时候一些不太好的实践......
  • 进程和任务管理器
    一、查看和控制进程1.1ps命令(1)ps命令——查看静态的进程统计信息(ProcessesStatistic)PIDTTYTIMECMD1579pts/100:00:00bash1730pts/100:00:00psPID:进程IDTTY  (进程id)TTY:表明该进程在哪个终端上运行。“?”表示未知或不需要终端。TIME:该进程占用的CPU时间C......
  • 进程任务管理
    一.  查看和控制进程    程序是保存在外部存储介质(如硬盘)中的可执行机器代码和数据的静态集合,而进程是在CPU及内存中处于动态执行的计算机程序。在Linux操作系统中,每个程序启动后可以创建一个或多个进程。列如,提供Web服务的httpd程序,当有大量用户同时访问Web页面时......
  • 线程池 + 回调 (进程赤用法类似)
    importosimportthreadingimporttimefromconcurrent.futuresimportThreadPoolExecutorfromfunctoolsimportwrapsThreadPool=ThreadPoolExecutor(max_workers=10)defthread_executor(a):print("Iamslave.Iamworking.Iamgoingtosleep3......
  • linux进程和计划任务管理
    一、查看和控制进程程序是保存在外部存储介质(如硬盘)中的可执行机器代码和数据的静态集合,而进程是在 CPU 及内存中处于动态执行状态的计算机程序。在 Linux 操作系统中,每个程序启动后可以创建一个或多个进程。例如,提供 Web 服务的 httpd 程序,当有大量用户同时访问Web......
  • Linux进程和计划任务管理
    查看和控制进程程序是保存在外部存储介质(如硬盘)中的可执行机器代码和数据的静态集合,而进程 是在CPU 及内存中处于动态执行状态的计算机程序。查看进程了解系统中进程的状态是对进程进行管理的前提,使用不同的命令工具可以从不同的 角度查看进程状态。1.ps命令——查看......
  • Linux进程替换 && 自主shell程序
        本篇将要讲解有关进程中最后一个知识点——进程替换,其中主要介绍有关进程替换的六个函数,直接从函数层面来理解进程替换(在使用函数的过程中,也会对进行替换进行解释)。本篇主要围绕如下的进程替换函数:    以上的exec*函数就是Linux中的加载函数,可以将......