Ase*_* Ka 0 c++ sockets select
我正在编写我的http服务器。我使用 select 函数,发现套接字已准备好随时写入,但只能在数千次迭代后才能读取。如果我使用 select(Max+1, &rfd, NULL, NULL, NULL),我就没有这样的问题。为什么经过这么多次迭代之后才准备好读取?
int iteration = -1;
while (true)
{
iteration++;
FD_ZERO(&rfd);
FD_ZERO(&wfd);
FD_SET(listeningSocket, &rfd);
for (std::set<int>::iterator Iter = servingSockets.begin(); Iter != servingSockets.end(); Iter++)
{
FD_SET(*Iter, &rfd);
FD_SET(*Iter, &wfd);
}
int Max = std::max(listeningSocket, *std::max_element(servingSockets.begin(), servingSockets.end()));
res = select(Max + 1, &rfd, &wfd, NULL, NULL);
if (res <= 0)
continue;
if (FD_ISSET(listeningSocket, &rfd))
{
if ((newSocket = accept(listeningSocket, (struct sockaddr *)&listeningSocketAddr, (socklen_t *)&listeningSocketAddr)) < 0)
continue;
fcntl(newSocket, F_SETFL, O_NONBLOCK);
servingSockets.insert(newSocket);
}
for (std::set<int>::iterator Iter = servingSockets.begin(); Iter != servingSockets.end();)
{
if (FD_ISSET(*Iter, &rfd))
{
std::cout<<"iter in loop: "<<iteration<<std::endl;
int bytes_recvd = recv(*Iter, request, request_buffer_size - 1, 0);
if (bytes_recvd < 0)
{
fprintf(stderr, "error recv\n");
shutdown(*Iter, SHUT_RDWR);
close(*Iter);
servingSockets.erase(*Iter);
continue;
}
request[bytes_recvd] = '\0';
parse_http_request(request, &req);
}
if (FD_ISSET(*Iter, &wfd) && req.path[0] != '\0')
{
send(*Iter, "HTTP/1.1 200 OK\n\n<h1><a href=\"\">external</a><br><a href=\"internal\">internal</a></h1>", 122, 0);
shutdown(*Iter, SHUT_RDWR);
close(*Iter);
Iter = servingSockets.erase(Iter);
continue;
}
Iter++;
}
}
Run Code Online (Sandbox Code Playgroud)
套接字始终是可写的,除非您填满了它的缓冲区。
因此select
每次调用都会立即返回,并将所有套接字标记为可写。
仅当您确实有东西要写入时,才将套接字添加到写入集中。一旦您写入了所需的所有内容,请将它们从集合中删除,并且不要将它们添加回来(直到下次需要写入套接字时)。
当您不使用写入集时,则select
在读取集中有一个活动的套接字之前,将不会返回。
归档时间: |
|
查看次数: |
137 次 |
最近记录: |