Linux 下服务器设计( 一 )
?这里讲的仅仅是一个简单的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 10typedef 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