日期:2014-05-16 浏览次数:20698 次
?这里讲的仅仅是一个简单的server的模型!为了处理同时来到很多小的链接请求( 解释:就是请求很简单,持续时间很短,那么if? server在请求到来时在fork来处理它,有可能fork的时间比应答请求的还要少,那么就是不合理的服务设计 ),所以我们采用的是“prefork”和“prethread”模型!
?
????? Unix 网络编程 上的4个模型是:prefork:主进程accept
??????????????????????????????????????????????????????????????????????????????? 子进程accept
??????????????????????????????????????????????????????????????? prethread:
???????????????????????????????????????????????????????????????????????????????? 主线程accept
???????????????????????????????????????????????????????????????????????????????? 子线程accept?? ( 姑且使用主线程和子线程来描述 )
?
?????? 第一部分是:使用“预先生成进程”处理
?
?????? CODE_1 : server是:主进程accept,那么这是4种方法中最复杂的,因为要涉及到进程间传递socket描述符的问题!( 进程间传递描述符在上一篇bolg中有过 !),server采用轮询的方式将socket传递给子进程!
? ? ?? 话不多说,贴上代码:
?Server:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/select.h> #include <sys/types.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/epoll.h> #include <fcntl.h> #define PORT 6000 #define MAXBACK 100 #define MAXLINE 1024 #define CHILD_NUM 10 typedef struct child_process { pid_t s_pid; //!> 子进程的pid int s_pipe_fd; //!> 与子进程通信的pipe口 int s_status; //!> 子进程的状态!0:闲 1:忙 }child_process; child_process child[CHILD_NUM]; //!> 定义10个子进程( 此处以10个为例 ) static int n_child_use = 0; //!> 几个child在工作( if 全忙就不给他们 ) //!> 发送socket描述符( 这个代码在上一篇博文上有 ) //!> int send_fd( int fd_send_to, void * data, size_t len, int sock_fd ) { struct msghdr msghdr_send; //!> the info struct struct iovec iov[1]; //!> io vector size_t n; //!> union { struct cmsghdr cm; //!> control msg char ctl[CMSG_SPACE(sizeof( int ))]; //!> the pointer of char }ctl_un; struct cmsghdr * pCmsghdr = NULL; //!> the pointer of control msghdr_send.msg_control = ctl_un.ctl; msghdr_send.msg_controllen = sizeof( ctl_un.ctl ); //!> design : the first info pCmsghdr = CMSG_FIRSTHDR( &msghdr_send ); //!> the info of head pCmsghdr->cmsg_len = CMSG_LEN(sizeof(int)); //!> the msg len pCmsghdr->cmsg_level = SOL_SOCKET; //!> -> stream mode pCmsghdr->cmsg_type = SCM_RIGHTS; //!> -> file descriptor *((int *)CMSG_DATA( pCmsghdr )) = sock_fd; //!> data: the file fd //!> these infos are nosignification