主函式
#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;
}