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 篇原創文章 · 獲贊 6 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章