socket connect()即使在对等重置后也返回0

时间:2013-09-02 12:54:21

标签: ios c sockets tcp posix

我有一个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()会暂停一段时间,然后返回-1errnoETIMEDOUT

从文档中,如果服务器拒绝连接尝试,我希望connect()返回-1errno返回ECONNREFUSEDECONNRESET 。相反,connect()会返回0

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

  

客户端(iPad) - &gt;服务器:SYN, ACK

     

服务器 - &gt;客户端(iPad):RST, ACK

为什么连接会返回0

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

1 个答案:

答案 0 :(得分:1)

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

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

在一天结束时,对于被拒绝的连接,connect()返回0并不重要。考虑一下:假设connect()成功,tcp连接建立并且调用返回0.但是,在代码更改为调用套接字上的写入或读取之前,服务器会立即重置或断开连接。下一次写入因EPIPE而失败,读取返回0。 无论如何,你需要处理这个案子。

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