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 *= (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 *= (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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值