gSOAP简单多线程服务器程序

gSOAP简单多线程服务器程序 
 
 
一 gSOAP需要的头文件:
//gsoap ns service name: calc
//gsoap ns service style: rpc
//gsoap ns service encoding: encoded
//gsoap ns service namespace: http://127.0.0.1:8089/calc.wsdl
//gsoap ns service location: http://127.0.0.1:8089/cal
//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">http://tempuri.org/">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">http://tempuri.org/">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 <MAX_THR; 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学习体会。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值