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