【问题标题】:why shutdown on udp socket blocks?为什么在 udp 套接字块上关闭?
【发布时间】:2014-09-05 08:06:16
【问题描述】:

我正在为 Windows 桌面/服务器编写一个 UDP 服务器应用程序。

我的代码使用windows建议的WSA API如下(这是我简化的receivePacket方法):

struct Packet
{
  unsigned int size;
  char buffer[MAX_SIZE(1024)];
}

bool receivePacket(Packet packet)
{
  WSABUFFER wsa_buffer[2];
  wsa_buffer[0].buf = &packet.size;
  wsa_buffer[0].len = sizeof(packet.size);
  wsa_buffer[1].buf = packet.buffer;
  wsa_buffer[1].len = MAX_SIZE;

  bool retval = false;
  int flags = 0;
  int recv_bytes = 0;
  inet_addr client_addr;
  int client_addr_len = sizeof(client_addr);

  if(WSARecvFrom(_socket, wsa_buffer, sizeof(wsa_buffer)/sizeof(wsa_buffer[0]), &bytes_recv, &flags, (sockaddr *)&client_addr, &client_addr_len, NULL, NULL) == 0)
  {
    //Packet received successfully
  }
  else
  {
    //Report
  }
}

现在,当我试图优雅地关闭我的应用程序时,不是在网络方面,而是在应用程序方面(通过所有的 d'tors 和东西),我试图取消阻止这个调用。

为此,我调用了shutdown(_socket, SD_BOTH) 方法。不幸的是,关闭自身的调用BLOCKS

在阅读了 MSDN 中所有可能的页面后,我没有找到任何关于为什么会发生这种情况、其他解决问题的方法或任何出路的参考。

我检查的另一件事是使用SO_RCVTIMEO。令人惊讶的是,这个 sockopt 也没有按预期工作。

我的代码/方法有什么问题吗?

【问题讨论】:

  • 您是否在程序开始时初始化了 WSA? SO_RCVTIMEO 的行为如何?可以添加socket创建和选项设置代码吗?
  • 这几乎是不可能的。该代码是在另一台未连接到网络的计算机上编写的。我确实初始化了WSA,初始化成功。这是我的程序创建的唯一套接字。我在调用绑定之后使用 setsockopt(_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) ,它返回零(成功)
  • 我在 MSDN 中发现了有关 SO_RCVTIMEO 选项的信息,这可能解释了为什么它的行为不像您预期​​的那样:“用于阻止接收呼叫的超时,以毫秒为单位。此选项的默认值为零,这表示接收操作不会超时。如果阻塞接收调用超时,则连接处于不确定状态,应关闭。如果使用 WSASocket 函数创建套接字,则 dwFlags 参数必须设置 WSA_FLAG_OVERLAPPED 属性超时才能正常工作。否则超时永远不会生效。"
  • 你读过这个吗:msdn.microsoft.com/en-us/library/windows/desktop/… 顺便说一句? cmets也有点担心。
  • 您是否尝试过仅使用SD_RECEIVE 而不是SD_BOTH?为什么要shutdown一个UDP套接字?

标签: c++ windows sockets networking udp


【解决方案1】:

您是否在重复的句柄上运行了关机?关闭同一句柄将等待此句柄上的任何活动操作完成。

【讨论】:

    猜你喜欢
    • 2018-05-26
    • 1970-01-01
    • 2018-06-24
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 2018-04-29
    相关资源
    最近更新 更多