单线程客户端处理多个socket连接的有关问题
单线程客户端处理多个socket连接的问题
程序要实现的功能:现在由n个DNS权威服务器,我依次向这些服务器发送同一个DNS查询请求,每次发送完用select监听描述符集,获取最先给出的DNS应答,但是程序目前每次轮询到的给出应答的连接都是最后一个建立的描述符,但是通过wireshark抓包,在这之前已经有服务器给出应答了,为什么select没有监听到?
------解决思路----------------------
what was the return value from select? select might return all available "ready to read" sockets in one call
------解决思路----------------------
code 没有问题,如果总是某个dns server 先返回ready,可以调换dns server 顺序试试
------解决思路----------------------
does select return the available socket immediately or it could put them in a queue in a certain amount of time?
程序要实现的功能:现在由n个DNS权威服务器,我依次向这些服务器发送同一个DNS查询请求,每次发送完用select监听描述符集,获取最先给出的DNS应答,但是程序目前每次轮询到的给出应答的连接都是最后一个建立的描述符,但是通过wireshark抓包,在这之前已经有服务器给出应答了,为什么select没有监听到?
int s, maxfd;
int tries, ns, i;
int n, sendlen, resplen;
struct sockaddr_in nsap, from;
socklen_t nsaplen, fromlen;
struct timeval timeout;
fd_set rset;
FD_ZERO(&rset);
maxfd = -1;
/* No name servers or res_init() failure */
if (statp->nscount == 0 ) {
goto fail;
}
/*
* Send request, RETRY times, or until successful.
*/
for (tries = 0; tries < statp->retry; tries++) {
for (ns = 0; ns < statp->nscount; ns++) {
/* Use datagrams. */
if(statp->socks[ns] == -1)
{
statp->socks[ns] = socket(PF_INET,SOCK_DGRAM,0);
setnonblocking(statp->socks[ns]);
}
s = statp->socks[ns];
printf("fd %d\n",s);
nsap = statp->nsaddr_list[ns];
nsaplen = sizeof(struct sockaddr_in);
if(connect(s,(struct sockaddr *)&nsap,nsaplen) == -1)
{
fprintf(stderr,"connect error\n");
goto fail;
}
sendlen = sendto(s,(const char *)buf,buflen,0,(struct sockaddr *)&nsap,nsaplen);
if(sendlen <= 0)
{
printf("send to failed\n");
goto fail;
}
if(sendlen != buflen)
{
printf("send to error\n");
goto fail;
}
FD_SET(s, &rset);
if(s > maxfd)
maxfd = s;
timeout.tv_sec = 0;
timeout.tv_usec = 90000;
n = select(maxfd+1, &rset, NULL, NULL, &timeout);
if (n == 0) {
printf("select timeout\n");
continue;
}
if (n < 0) {
printf("select error\n");
goto fail;
}
for(i=0;i<=ns;i++)
{
if(FD_ISSET(statp->socks[i],&rset))
{
printf("active fd %d\n",statp->socks[i]);
fromlen = sizeof(from);
resplen = recvfrom(statp->socks[i], (char*)ans, anssiz,0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
printf("recvfrom error\n");
goto fail;
}
return resplen;
}
}
} /*foreach ns*/
} /*foreach retry*/
res_nclose(statp);
return -1;
fail:
res_nclose(statp);
return -1;
------解决思路----------------------
what was the return value from select? select might return all available "ready to read" sockets in one call
------解决思路----------------------
code 没有问题,如果总是某个dns server 先返回ready,可以调换dns server 顺序试试
------解决思路----------------------
does select return the available socket immediately or it could put them in a queue in a certain amount of time?