Chinaunix首页 | 论坛 | 博客
  • 博客访问: 590537
  • 博文数量: 226
  • 博客积分: 10080
  • 博客等级: 上将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-26 11:15
文章分类

全部博文(226)

文章存档

2011年(5)

2010年(64)

2009年(99)

2008年(37)

2007年(21)

我的朋友

分类: LINUX

2007-11-26 17:30:07

一 gSOAP需要的头文件:

//gsoap ns service name: calc
//gsoap ns service style: rpc
//gsoap ns service encoding: encoded
//gsoap ns service namespace: 

//gsoap ns service location: 
//gsoap ns schema  namespace:    urn:calc
int ns__add(double a, double b, double *result);
int ns__sub(double a, double b, double *result);
int ns__mul(double a, double b, double *result);
int ns__div(double a, double b, double *result);
int ns__pow(double a, double b, double *result);

二 多线程服务器关键代码

#include 
#include  "calc.nsmap"
#include  "soapH.h"

/////////////////////////////////////////////////////////////////////////
///宏与全局变量的定义
#define  BACKLOG (100) 
#define  MAX_THR (10)  
#define  MAX_QUEUE (1000)


pthread_mutex_t queue_cs;                        //队列锁
pthread_cond_t  queue_cv;                          //条件变量
SOAP_SOCKET     queue[MAX_QUEUE];   //数组队列
int                           head =0, tail =0;          //队列头队列尾初始化        
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
void *      process_queue(void *);        //线程入口函数
int         enqueue(SOAP_SOCKET);  //入队列函数
SOAP_SOCKET dequeue(void);         //出队列函数

//////////////////////////////////////////////////////////////////////////
//线程入口函数
void * process_queue(void * soap)
{
  struct soap * tsoap = (struct soap *)soap;
  for(;;)
  {
        tsoap->socket = dequeue();
        if (!soap_valid_socket(tsoap->socket))
       {
         break;
        }
        soap_serve(tsoap);
        soap_destroy(tsoap);
        soap_end(tsoap);
  }
  return NULL;
}

//入队列操作
int enqueue(SOAP_SOCKET sock)
{
  int status = SOAP_OK;
  int next;
  pthread_mutex_lock(&queue_cs);
  next = tail +1;
  if (next >= MAX_QUEUE)
    next = 0;
  if (next == head)
      status = SOAP_EOM;
  else
  {
    queue[tail] =sock;
    tail = next;
  }
  pthread_cond_signal(&queue_cv);
  pthread_mutex_unlock(&queue_cs);
  return status;
}

//出队列操作
SOAP_SOCKET dequeue()
{
  SOAP_SOCKET sock;
  pthread_mutex_lock(&queue_cs);
   while (head == tail )
   {
          pthread_cond_wait(&queue_cv,&queue_cs);
   }
  sock = queue[head++];
  if (head >= MAX_QUEUE)
        {
    head =0;
  }
  pthread_mutex_unlock(&queue_cs);
  return sock;
}


//////////////////////////具体服务方法////////////////////////////////////////
//加法的实现
int ns__add(struct soap *soap, double a, double b, double *result)
{
      *result = a + b;
      return SOAP_OK;
}
//减法的实现
int ns__sub(struct soap *soap, double a, double b, double *result)
{
     *result = a - b;
     return SOAP_OK;
}
//乘法的实现
int ns__mul(struct soap *soap, double a, double b, double *result)
{
     *result = a * b;
     return SOAP_OK;
}
//除法的实现
int ns__div(struct soap *soap, double a, double b, double *result)
{
   if (b)
       *result = a / b;
   else
  {
         char *s = (char*)soap_malloc(soap, 1024);
         sprintf(s, "Can't">">Can't divide %f by %f", a, b);
         return soap_sender_fault(soap, "Division by zero", s);
  }
  return SOAP_OK;
}
//乘方的实现
int ns__pow(struct soap *soap, double a, double b, double *result)
{
  *result = pow(a, b);
  if (soap_errno == EDOM) /* soap_errno 和errorno类似, 但是和widnows兼容 */
  {
    char *s = (char*)soap_malloc(soap, 1024);
    sprintf(s, "Can't take the power of %f to  %f", a, b);
    sprintf(s, "Can't">">Can't take power of %f to %f", a, b);
    return soap_sender_fault(soap, "Power function domain error", s);
  }
  return SOAP_OK;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
//主函数
int main(int argc,char ** argv)
{
  struct soap ServerSoap;
     //初始话运行时环境
    soap_init(&ServerSoap);
    //如果没有参数,当作CGI程序处理
    if (argc <2)
    {      
           //CGI 风格服务请求,单线程
          soap_serve(&ServerSoap);
          //清除序列化的类的实例
         soap_destroy(&ServerSoap);
         //清除序列化的数据
        soap_end(&ServerSoap);    
   }else
   {
     struct soap * soap_thr[MAX_THR];
     pthread_t tid[MAX_THR];
     int i,port = atoi(argv[1]);
     SOAP_SOCKET m,s;
      //锁和条件变量初始化
     pthread_mutex_init(&queue_cs,NULL);
     pthread_cond_init(&queue_cv,NULL);
     //绑定服务端口
    m = soap_bind(&ServerSoap,NULL,port,BACKLOG);
    //循环直至服务套接字合法
    while (!soap_valid_socket(m))
   {
                fprintf(stderr,"Bind port error! ");
                m = soap_bind(&ServerSoap,NULL,port,BACKLOG);
    }
    fprintf(stderr,"socket connection successful %d ",m);
               
     //生成服务线程
    for(i = 0; i

   {
      soap_thr[i] = soap_copy(&ServerSoap);
      fprintf(stderr,"Starting thread %d ",i);
      pthread_create(&tid[i],NULL,(void*(*)(void*))process_queue,(void*)soap_thr[i]);
    }
               
    for(;;)
    {
      //接受客户端的连接
      s = soap_accept(&ServerSoap);
      if (!soap_valid_socket(s))
      {
        if (ServerSoap.errnum)
                                {
          soap_print_fault(&ServerSoap,stderr);
          continue;
        }else
        {
          fprintf(stderr,"Server timed out ");
          break;
        }
      }
       //客户端的IP地址
      fprintf(stderr,"Accepted connection from IP= %d.%d.%d.%d socket = %d ",
                               ((ServerSoap.ip)>>24)&&0xFF,((ServerSoap.ip)>>16)&0xFF,((ServerSoap.ip)>>8)&0xFF,(ServerSoap.ip)&0xFF,(ServerSoap.socket));
      //请求的套接字进入队列,如果队列已满则循环等待
       while(enqueue(s) == SOAP_EOM)
                Sleep(1000);
    }
    //服务结束后的清理工作
    for(i = 0; i < MAX_THR; i++)
    {
      while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM) 
       {
           Sleep(1000);
      }
    }
    for(i=0; i< MAX_THR; i++)
    {
      fprintf(stderr,"Waiting for thread %d to terminate ..",i);
      pthread_join(tid[i],NULL);
      fprintf(stderr,"terminated ");
      soap_done(soap_thr[i]);
      free(soap_thr[i]);
    }
    pthread_mutex_destroy(&queue_cs);
    pthread_cond_destroy(&queue_cv);
  }
    //分离运行时的环境
  soap_done(&ServerSoap);
  return 0;
}

 

三 具体使用方法见gSOAP学习体会。


阅读(8176) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~