问题:

在使用线程池处理客户端请求时发现不能获取到客户端的ip!

原因:


    由于在server_loop注循环中只把连接字sock加到queue队列中,并没有客户端IP,所以每一次queue回调函数只能取得sock连接字,没有客户端的ip


解决方法:


    在将sock加入queue队列的同时把ip也加入到ips队列中,ips队列的长度和queue相同,而且存的数据下标要相同,取sock处理时也把IP取出来,即可得到了客户端IP



步骤:


    定义全局保存IP地址的变量



static unsigned long ips[MAX_QUEUE];


    修改 enqueue函数



int enqueue(SOAP_SOCKET sock,unsigned long ip)//添加ip的参数
{
int status = SOAP_OK;
int next;
int ret;
if ((ret = MUTEX_LOCK(queue_cs)))
fprintf(stderr, "MUTEX_LOCK error %d\n", ret);
next = (tail + 1) % MAX_QUEUE; //1000
if (head == next)
{
/* don't block on full queue,
* 队列已满,return SOAP_EOM */
status = SOAP_EOM;
}
else
{
queue[tail] = sock;
ips[tail] = ip; //保存ip
tail = next;
if ((ret = COND_SIGNAL(queue_cv)))
fprintf(stderr, "COND_SIGNAL error %d\n", ret);
}
if ((ret = MUTEX_UNLOCK(queue_cs)))
fprintf(stderr, "MUTEX_UNLOCK error %d\n", ret);
return status;
}



    添加dequeue_ip()函数



unsigned long  dequeue_ip()
{
unsigned long ip;
int num=0;
if(head == 0)
num = MAX_QUEUE - 1;
else
num = head -1;
ip = ips[num];
return ip;
}




修改queue回调函数函数



void *process_queue(void *soap)
{
struct soap *tsoap = (struct soap*)soap;
for (;;)
{
tsoap->socket = dequeue();
tsoap->ip = dequeue_ip();//获取相应的ip地址
if (!soap_valid_socket(tsoap->socket))
{
#ifdef DEBUG
fprintf(stderr, "Thread %d terminating\n", (int)(long)tsoap->user);
#endif
break;
}



解决!



测试:


在http_get_handler函数中测试



int http_get_handler(struct soap *soap)

。。。。。
fprintf(stderr, "Request accepts connection from IP %d.%d.%d.%d\n",
(int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF,(int) (soap->ip>>8)&0xFF, (int)soap->ip&0xFF);
。。。。。。
}



输出:



Request accepts connection from IP 192.168.1.136
Request accepts connection from IP 192.168.1.136
Thread 3 finished serving request with failure 404
Error 404 fault: SOAP-ENV:Client [no subcode]
"HTTP Error: 404 Not Found"
Detail: [no detail]
Request accepts connection from IP 192.168.1.87
Request accepts connection from IP 192.168.1.87
Request accepts connection from IP 192.168.1.87