c - 由于连接突发,套接字连接被拒绝

标签 c sockets parallel-processing synchronization

我使用套接字来同步多个远程进程。

这个想法是一个进程创建一个管理服务器端的pthread,就像这样:

void *listener(void * in) {
  int sockfd;
  socklen_t clilen;
  struct sockaddr_in serv_addr, cli_addr;
  int n = *((int *) in);

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0)
      error("ERROR opening socket");

  int option = 1;
  setsockopt(sockfd, SOL_SOCKET, (SO_REUSEPORT | SO_REUSEADDR), (char*) &option, sizeof (option));
  bzero((char *) &serv_addr, sizeof (serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(PORT);

  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
      error("ERROR on binding");

  if (listen(sockfd, n) < 0)
      error("ERROR when listening");

  clilen = sizeof (cli_addr);
  int cnt = 0;
  while (cnt < n) {
      int newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
      if (newsockfd < 0) {
          error("ERROR on accept");
      }
      cnt++;
  }
  close(sockfd);
  return 0;
}

同时,其他进程将执行:

int sockfd;
struct sockaddr_in serv_addr;
struct hostent *server;

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
  error("ERROR opening socket");

server = gethostbyname(_managementHost); //managementHost);
if (server == NULL)
  error("ERROR, no such host\n");

bzero((char *) &serv_addr, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(PORT);

if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
  error("ERROR connection");

close(sockfd);

现在,我遇到的问题是,当我有很多进程尝试同时连接到服务器时,其中一些进程会抛出连接被拒绝错误。

我猜这是因为接受可能还没有准备好......事实上,我已经读到它可能会发生,但我还没有找到我的具体情况。

有人能解释一下这个问题吗?

我想到的一个可能的解决方案是为每个接受创建一个线程,但我宁愿避免它。

谢谢。

编辑:更正了服务器中套接字的双重初始化。感谢@Remy Lebeau。

最佳答案

Now, the problem I have is when I have a lot of processes trying to connect at the same time to the server, some of them are throwing connection refused errors.

监听 TCP 套接字积压了待处理的连接。 listen() 的第二个参数指定在接受之前积压队列中允许有多少个连接。如果新客户端在积压已满时尝试连接,则该客户端将被拒绝。客户端或服务器对此无能为力。客户端有责任检测错误并稍后重新连接。

您的 listener() 正在接受客户端,直到达到指定的连接数,但您也使用相同的数字作为监听积压队列大小。事件连接数和待处理连接数是两个不同的东西。如果您预计有很多客户端同时连接,则需要较大的积压大小以避免拒绝错误。但积压的大小应与您预期的流量成正比。如果您有 1000 个客户端,但它们一次仅连接 20 个,您可以将待办事项设置为 25,而不是 1000。

您的listener()还有一些其他逻辑错误。它调用了 socket() 两次,并将两个套接字保存到同一个 sockfd 变量中,因此它泄漏了第一个套接字。您需要删除对 socket() 的第二次调用(setsockopt() 之前的调用)。您还泄漏了 accept() 返回的套接字。在使用已接受的套接字后,您需要close()它。

关于c - 由于连接突发,套接字连接被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39626253/

相关文章:

Java - 为什么等待多个信号量不起作用?

c - c中数组内容不一致

c++ - boost::asio::ip::tcp::socket 不读取任何内容

c - gdb 回溯显示 malloc

sockets - 为什么TCP套接字编程需要两个套接字(一个欢迎套接字和一个连接套接字)而UDP只需要一个?

iPhone 套接字流行为 - 将字节发送到服务器.. NSStream/CFStream

python - 多处理器环境下的 scikit-learn 网格搜索

c - 使用 OpenMP 进行 LU 分解似乎很慢,需要建议

c - 我如何知道两个exe是否有不同的代码?

c - struct.field 返回另一个值,为什么?