【问题标题】:How to check if other end of a socket has been accepted?如何检查套接字的另一端是否已被接受?
【发布时间】:2023-04-09 17:24:01
【问题描述】:

我设置了客户端/服务器,我希望我的客户端知道服务器是否已接受连接。否则我的客户不知道它仍在等待被接受。我不能依靠进一步的通信(协议规范)来验证这一点。因此,例如,从服务器向客户端发送“Good to go”字符串不是一种选择。是否有标志或其他东西可以检查服务器是否确实在接收?一些示例代码如下:

/* Client */
...
getaddrinfo(ip, port, &hints, &servinfo);
connect(sockfd, info->ai_addr, info->ai_addrlen);

if (info == NULL) {
    printf("connection failure\n");
    exit(1);
}

inet_ntop(info->ai_family, get_in_addr((struct sockaddr *)info->ai_addr), ipstring, sizeof(ipstring));
printf("Connected to %s!\n", ipstring);
...

/* Server */
...
pause(); /* If don't accept the connection, how to make the client know? */ 
new_fd = accept(sockfd, (struct sockaddr *)&cli_addr, &addr_size);
...

【问题讨论】:

  • 如果没有接受,说明没有连接,在客户端会超时。你需要另一个连接来做你想做的事,这只会解决问题。为了发送它没有接受,它需要接受连接才能做到......
  • 在任何情况下检查系统调用的返回值都是一个好主意。如果这样表示错误,检查errno 的值,如果手册页声明它设置为错误,将提供更多启发。
  • 我已经检查了所有内容,为简洁起见,它们没有包括在内。

标签: c linux sockets unix-socket


【解决方案1】:

您应该检查来自connect() 的返回值,因为它将通过errno 指示失败的原因。

在您的情况下,connect() 调用将超时,因此 connect() 将返回 -1 并且 errno 设置为 ETIMEDOUT

  int ret = connect(sockfd, info->ai_addr, info->ai_addrlen);
  if (ret == -1) {
      /* connect failed */
      switch(errno) {
      case ETIMEDOUT:
             /* your server didn't accept the connection */
      case ECONNREFUSED:
             /* your server isn't listening yet, e.g. didn't start */
      default:
             /* any other error, see man 2 connect */
      }
  }

【讨论】:

  • 啊,我的错。我忘了包括我有一个待办事项,以确保我不会断开任何连接。放弃积压并实施某种指数重试方法在客户端连接会更好吗?
  • 检查ETIMEDOUT 应该可以完成这项工作。另一种选择是重写服务器应用程序以异步处理连接并接受连接以供以后处理。你可能想看看libevent
  • 不再有客户端的限制因素不在于套接字,因此永远不会触发 ETIMEDOUT。我会调查 libevent 看看他们是否有我需要的任何实现,谢谢
【解决方案2】:

由于积压,服务器可以在接受呼叫之前发送 SYN-ACK。所以客户端调用connect()可以在服务器调用accept()之前返回。

正如您所说:来自服务器的“Good to go”消息不是选项。 怎么样:来自客户的“回声”请求。所以服务器接受后会响应。

如果 TCP 流中有任何额外的流量不是一个选项。可以使用辅助数据吗?

【讨论】:

  • 我相信辅助数据是可以接受的,即使不是,我仍然很想知道这种方法将如何解决这个问题。您能举个例子吗?
猜你喜欢
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
  • 1970-01-01
  • 2012-05-19
  • 2011-10-28
  • 1970-01-01
  • 2019-02-06
相关资源
最近更新 更多