日期:2014-05-16  浏览次数:20698 次

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   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