【问题标题】:socket connect() returning 0 even after peer reset即使在对等重置之后,socket connect() 也会返回 0
【发布时间】:2013-09-05 14:21:45
【问题描述】:

我有一个 iPad 应用程序,我正在其中创建和连接一个 posix socket。当远程设备拒绝连接尝试时,对connect(...) 的调用没有按预期响应。

我如何创建和连接socket 的简化示例:

struct sockaddr_in server;
server.sin_family = AF_INET;

int socket = socket(AF_INET, SOCK_STREAM, 0);
if(socket < 0)
{
  NSLog(@"socket create failed: %s", strerror(errno));
}
else if(inet_aton(mAddress, &server.sin_addr))
{
  server.sin_port = htons(mPortNumber);
  if(connect(socket, (struct sockaddr *)&server, sizeof(server)) == -1)
  {
    NSLog(@"connect() failed: %s", strerror(errno));
  }
  else
  {
    NSLog(@"connect() succeeded");
  }
}

在大多数情况下,上述示例有效:例如对于正在接受连接的远程设备(以下称为“服务器”),connect() 按预期返回0。对于不存在的地址,connect() 会阻塞一段时间然后返回-1,而errnoETIMEDOUT

从文档中,如果服务器拒绝连接尝试,我希望 connect() 返回 -1 并且 errnoECONNREFUSED 或者可能是 ECONNRESET。相反,connect() 返回0

我已经多次对 TCP 会话进行 WireSharked,并且可以确认它只包含两个数据包:

客户端 (iPad) -> 服务器:SYN, ACK

服务器 -> 客户端(iPad):RST, ACK

为什么连接返回0

更新:从不同的客户端连接到同一台服务器,例如Windows(winsock?)或 Mac OSX(也是 posix)上的 Qt 按预期工作:即 connect() 返回 -1ECONNREFUSED。这让我相信这是 iPad 端而不是服务器端的问题。

【问题讨论】:

  • "...如果远程设备拒绝连接尝试..." 我不确定to reject 是否是一个明确定义的 tcp/ip 操作连接设置,因此您可能想详细说明如何定义它。
  • 我所说的“拒绝连接”是指与上面的 TCP 会话类似,即客户端尝试SYN,服务器回复RST。你会用什么术语来描述这个?
  • 没有SYN-ACK 从遥控器响应 iPad 的 SYN?
  • 不,只是RST, ACK,如上所述。如果有帮助,我会尝试附加完整的wireshark输出?
  • 我不敢提这个,但iPad似乎肯定有什么东西要坏了。立即为SYN 获取RST 应该会在客户端导致ECONNREFUSED

标签: ios c sockets tcp posix


【解决方案1】:

我认为你应该这样创建套接字,注意第三个参数。

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

归根结底,connect() 为拒绝连接返回 0 并不重要。考虑一下:假设 connect() 成功,tcp 连接建立并且调用返回 0。但是,在您的代码更改为在套接字上调用 write 或 read 之前,服务器会立即重置或断开连接。下一次写入因 EPIPE 失败,读取返回 0。 无论如何,你需要处理这种情况。

我假设您已经阅读了这篇文章,但请注意在 iOS 中使用 POSIX 套接字时需要注意:https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html

【讨论】:

    猜你喜欢
    • 2017-10-01
    • 2011-07-16
    • 1970-01-01
    • 2012-07-14
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多