gpt4 book ai didi

在 tcp 套接字请求中的线程进程上一段时间后连接被拒绝 (c/linux)

转载 作者:行者123 更新时间:2023-11-30 16:05:29 24 4
gpt4 key购买 nike

我正在尝试创建每秒处理多个请求的进程,每个请求都会创建新线程。然后每个线程打开到地址(http 端口)的套接字连接,发送 HEAD 请求,获取响应并关闭套接字。
当我每秒发出超过 3 个请求时,我遇到的问题就出现了,一段时间后,我在函数的 send() 部分遇到错误,我不断收到连接被拒绝的消息。如果我每秒输入更多请求,我会更早收到错误。如果我每秒只发出 2 个请求,我根本不会收到错误。我怀疑我的某些资源用完了,但我找不到哪个资源。

这是代码的基本结构

//declarations

socketfd = socket(servinfo->ai_family,servinfo->ai_socktype,servinfo->ai_protocol);

arg = fcntl(socketfd, F_GETFL, NULL)) < 0);
arg |= O_NONBLOCK;
fcntl(socketfd, F_SETFL, arg)

if((conn = connect(socketfd, servinfo->ai_addr, servinfo->ai_addrlen)) < 0)
{
if(errno == EINPROGRESS)
{
do
{
tv.tv_sec = CONNECT_TIMEOUT;
tv.tv_usec = 0;
FD_ZERO(&myset);
FD_SET(socketfd, &myset);
if((res = select(socketfd+1, NULL, &myset, NULL, &tv) > 0))
{
if( (arg = fcntl(socketfd, F_GETFL, NULL)) < 0) {
perror("fcntl get 2");
}
arg &= (~O_NONBLOCK);
if( fcntl(socketfd, F_SETFL, arg) < 0) {
perror("fcntl set 2");
}
char szBuf[4096];

std::string htmlreq = "HEAD / HTTP/1.1\r\nHost:";
htmlreq += info->hostName;
htmlreq += "\r\n\r\n";

if((conn = send(socketfd,htmlreq.c_str(),htmlreq.size(),0)) == -1 && errno != EINTR)
{
perror("send");
close(socketfd);
return;
}

if((conn = recv(socketfd,szBuf,sizeof(szBuf)+1,0)) < 0 && errno != EINTR)
{
perror("recv");
close(socketfd);
return ;
}

close(socketfd);

// do stuff with data
break;
}
else
{
//timeout
break;
}
}while(1);
}
else
{
perror("connect");
close(socketfd);
return;
}
}

我从一开始就删除了一些错误检查,一段时间后我得到的输出是“发送:连接被拒绝”。我希望能得到一些指示,指出哪些部分可能导致问题,平台是 ubuntu linux。如果需要的话,我也很乐意发布代码的其他部分。提前Tnx。

最佳答案

您可能耗尽的资源位于您正在连接的服务器上。您正在连接的计算机拒绝连接,因为它是:

  1. 配置为限制每秒连接数(基于某些标准)
  2. 或者您要连接的服务器由于某种原因负载过高,无法再接受任何连接。

由于您总是在第三个连接上收到错误,因此可能是您要连接的服务器限制了每个 IP 的连接数。

编辑1

您正在尝试进行非阻塞连接吗?现在我仔细看看它,听起来你的问题出在 select 上,因为 select 在实际连接之前返回套接字是可读的,然后你调用 send。在非阻塞连接上需要注意的事情之一是套接字在发生错误时变得可读和可写。这意味着您需要在 select 返回后检查两者,否则您可能会错过任何实际错误并看到发送错误。

这是来自 Stevens UNP:

FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset;
tval.tv_sec = nsec;
tval.tv_usec = 0;

if ( (n = Select(sockfd+1, &rset, &wset, NULL,
nsec ? &tval : NULL)) == 0) {
close(sockfd); /* timeout */
errno = ETIMEDOUT;
return(-1);
}

if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
len = sizeof(error);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return(-1); /* Solaris pending error */
} else
err_quit("select error: sockfd not set");

done:
Fcntl(sockfd, F_SETFL, flags); /* restore file status flags */

if (error) {
close(sockfd); /* just in case */
errno = error;
return(-1);
}
return(0);

关于在 tcp 套接字请求中的线程进程上一段时间后连接被拒绝 (c/linux),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/847462/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com