Windows UDP 套接字:recvfrom() 失败并出现错误 10054

2023-11-21


大家好。
我正在尝试使用 Windows 套接字发送和接收 UDP 数据包(在 C++ 中)。
它一直运行良好,直到三天前程序停止正常运行。
总结一下情况:

  • 当在我的套接字上调用 WSAPoll() 时,即使没有启动服务器,它也总是返回用所有可能的 revents 更新的套接字(对应于我给 pollfd 的每个事件)。
  • 当调用recvfrom()并且没有启动服务器时,它返回SOCKET_ERROR,错误代码为10054(*)。
  • 当调用 recvfrom() 并启动服务器时,它会正常工作 - 阻塞直到收到某些内容。
  • 无论我尝试连接到本地主机还是远程主机,行为都是相同的。

(*) 我调查了这个错误。在UDP中,这意味着存在ICMP问题。 (“在 UDP 数据报套接字上,此错误表明先前的发送操作导致了 ICMP 端口不可达消息。”)。
我确实在recvfrom()之前调用了sendto(),所以问题不在这里。
我试图关闭防火墙,看看它是否改变了任何东西,但没有改变。我还尝试关闭流经我电脑的所有网络。在这种状态下,我设法让程序运行了几分钟,但是当我启用网络时,它再次停止运行。我试图重复这个过程,但它不再起作用了。
我尝试使用 Visual Studio (2015) 和 MinGW 进行编译。
我也在另一台电脑上尝试过(Windows 7下,我的是Windows 8.1),但无济于事。

这是一个简单的测试文件,在我的计算机上不起作用。

#undef _WIN32_WINNT
#define _WIN32_WINNT 0x501
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <vector>
#include <iostream>

int main() {
  int clientSock;
  char buf[100];
  int serverPort;

  /* Initializing WSA */
  WSADATA wsaData;
  WSAStartup(MAKEWORD(2, 2), &wsaData);

  /* I create my socket */
  struct addrinfo specs;
  struct addrinfo *addr = new addrinfo;
  ZeroMemory(&specs, sizeof(specs));
  specs.ai_family = AF_INET;
  specs.ai_socktype = SOCK_DGRAM;
  specs.ai_flags = 0;
  getaddrinfo("127.0.0.1", "2324", &specs, &addr);

  clientSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

  /* I get the server's address */
  struct sockaddr_in serverAddr;
  serverAddr.sin_family = AF_INET;
  serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  serverAddr.sin_port = htons(2324);
  int len = sizeof(struct sockaddr);

  /* I'll poll & recvfrom on my socket */
  std::vector<pollfd> fds;
  pollfd fd;
  fd.fd = clientSock;
  fd.events = POLLRDNORM;
  fd.revents = -1;
  fds.push_back(fd);

  while(1) {
    memset(buf,0,sizeof(buf));
    printf("\nClient--->: ");
    gets(buf);
    /* It's UDP, so it doesn't matter if there is someone to receive the packet */
    sendto(clientSock, buf, strlen(buf), 0, (sockaddr*)&serverAddr ,len);

    memset(buf,0,sizeof(buf));
    int ret;
    /* Always returns "1" */
    if ((ret = WSAPoll(fds.data(), 1, 0)) > 0) {
      std::cout << ret;
      /* Always returns "-1" */
      std::cout << recvfrom(clientSock,buf,sizeof(buf),0, (sockaddr*)&serverAddr,&len) << std::endl;
      printf("\n--->From the server: ");
      printf("%s",buf);
    }
  }

  closesocket(clientSock);
  WSACleanup();

  return 0;
}

两个问题:

  1. 为什么 WSAPoll() 总是返回更新的套接字,即使没有与之进行任何交互?
  2. 为什么 recvfrom() 返回此错误以及如何修复它?我想它来自我的电脑。我尝试允许 ICMP 通过我的防火墙,但它没有改变任何内容,也许我做错了什么?

编辑:我通过忽略收到的任何“错误 10054”来修复我的主程序(此处未显示,因为它太大)。现在它的工作方式与 Unix 上相同。
尽管如此,这并不是一个真正的解决方案(忽略错误代码......meh),如果有人知道为什么我在调用时收到“ICMP Port Unreachable”错误sendto(),我很高兴听到这个消息。


在Windows中,如果主机A使用UDP套接字并调用sendto()发送一些东西给主机B,但是B没有绑定任何端口,所以B收不到消息,然后主机A调用recvfrom()接收一些消息,recvfrom()将失败,并且WSAGetLastError()将返回10054.

这是 Windows 的一个错误。如果UDP套接字在发送消息后接收到ICMP(端口不可达)消息,则该错误将被存储,并在下次调用recvfrom()将返回此错误。

有两种方法可以解决这个问题:

  1. 确保主机 B 已经绑定了您要发送到的端口。
  2. 使用以下代码禁用此错误:
#include <Winsock2.h>
#include <Mstcpip.h>
#include <stdio.h>

#pragma comment(lib, "ws2_32.lib")
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)

BOOL bNewBehavior = FALSE;
DWORD dwBytesReturned = 0;
WSAIoctl(iSock, SIO_UDP_CONNRESET, &bNewBehavior, sizeof bNewBehavior, NULL, 0, &dwBytesReturned, NULL, NULL);

参考:http://www.cnblogs.com/cnpirate/p/4059137.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows UDP 套接字:recvfrom() 失败并出现错误 10054 的相关文章

  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • Windows C++ 中的键盘钩子还是什么?

    我希望构建自己的应用程序 它可以将键盘命令 消息 发送到 Windows 操作系统 例如 当我按下组合键 ctrl shift n 时 我希望启动 notepad exe 我怎样才能做到这一点 您对所使用的概念有什么建议吗 我读过 何时使用
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new

随机推荐

  • 如何拍摄 Android 模拟器状态的快照?

    当我从以下位置启动 Android 模拟器时Android SDK 和 AVD 管理器我可以勾选这些框从快照启动 and 保存到快照以便在关闭模拟器时保存模拟器的状态 并在启动模拟器时再次恢复状态 这很棒 因为我不必在每次启动模拟器时都等待
  • $lookup 数组中的 ObjectId

    在 ObjectId 数组而不仅仅是单个 ObjectId 字段上执行 lookup 的语法是什么 订单文档示例 id ObjectId products ObjectId
  • 为什么 Visual Studio Code 中文件资源管理器中的子文件夹会折叠成一行?

    我对 VS Code 比较陌生 我想我一定是不小心更改了设置 VS Code 过去常常清晰地显示下面的所有子文件夹 并从其父文件夹向右缩进 但有些事情发生了变化 现在我的子文件夹显示有点像文件资源管理器中的面包屑 请参见下面发布的图片 我尝
  • 将包含日数据的 JFreeChart TimeSeries 系列转换为周或月数据?

    我意识到这可能是一个愚蠢的问题 并且我知道可以通过确定每个数据点所在的周或月等来完成 但是 我正在寻找一种避免编码的方法 如果它是在图书馆中完成的 大概所有的陷阱都得到了 我宁愿使用它 原始数据存储在Excel电子表格中 但我无法直接操作电
  • 输出原始图像流而不是 jpeg,动态调整图像大小

    我有一个 PHP 函数 可以动态调整图像大小以创建缩略图 我遇到了麻烦 因为它只是显示原始图像流而不是实际图像 我的代码使用一个名为缩略图的函数 thumbnail thumbnail item filename 209 137 image
  • PHP date('W') 与 MySQL YEARWEEK(now())

    有人可以解释一下为什么这两个给出不同的结果吗 我用 PHP 执行这个 date YW mktime 0 0 0 3 22 2013 outputs 201312 当我使用 MySQL 执行此操作时 SELECT YEARWEEK now o
  • HTMLUnit:执行速度超慢?

    我一直在使用 HTMLUnit 它非常适合我的要求 但似乎速度极其缓慢 例如 我使用 HTMLUnit 自动化了以下场景 Goto Google page Enter some text Click on the search button
  • Postgresql:带有转义换行符的 CSV 导出

    我使用此处发布的 所有 指令从 postgresql 数据库导出了一些数据 将 PostgreSQL 的 PL pgSQL 输出保存到 CSV 文件 但某些导出的字段包含换行符 换行符 因此我得到了一个 CSV 文件 如下所示 header
  • 调试的最佳实践

    最近 我使用 Visual Studio 和 WinDbg 对托管应用程序进行了大量调试 因此我经常被要求协助同事进行调试 有好几次我发现人们只是到处插入断点并希望得到最好的结果 根据我的经验 这很少是一种有用的技术 我的方法是这样的 重现
  • 通过 GraphQL API 显示超过 100 个条目

    我已经厌倦了使用 github grpahQL API 中的 endCursor 和 hasNextPage 进行分页来获取超过 100 个数据 我使用的查询是 query organization login XXX repository
  • 动态创建的元素上的事件绑定?

    这个问题的答案是社区努力 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我有一些代码 我循环遍历页面上的所有选择框并绑定 hover事件让他们在宽度上做一些调整mouse on off 这发生在页面准备好并且工作得很好 我遇到的问题
  • 获取调整大小的 html 图像元素的原始尺寸

    有没有一种简单有效的方法来获取显示在 JavaScript 中的图像的真实尺寸 在 JavaScript 中 img 具有可能不同渲染大小的元素 例如 通过max height or max width 有存在naturalWidth an
  • 使用 GraphicsEnvironment 取消注册字体?

    我最近发现了如何向本地 GraphicsEnvironment 注册 TTF 字体 对于我的用例 SVG 到 PNG 转码 Apache Batik 可能会识别该字体 import java awt Font import java awt
  • 运行 ASP.NET Web 应用程序时找不到 System.Runtime 4.1.0.0

    我使用以下projects json 创建了一个可移植类库 supports dependencies Microsoft CSharp 4 0 1 Microsoft NETCore Portable Compatibility 1 0
  • 使用 Visual Studio 在源代码中显示日语字体

    我有一些源文件 其中有用日语写的注释 当我在 Visual Studio 中打开这些文件时 它们显示如下 FNCAP p X b h 我使用的是英文版 WinXP 但是有没有办法让 Visual Studio 显示实际的日语字符而不是当前的
  • 将自定义模型绑定器应用于asp.net core中的对象属性

    我正在尝试为模型的 DateTime 类型属性应用自定义模型绑定器 这是 IModelBinder 和 IModelBinderProvider 的实现 public class DateTimeModelBinderProvider IM
  • 获取与 c# 中的 ProcessStartInfo 一起使用的可用动词(文件关联)列表

    我正在尝试使用 ProcessStartInfo 类打开和打印文件 文件可以是任何内容 但我们假设它是 PDF 文件 ProcessStartInfo pi new ProcessStartInfo file pi Arguments Pa
  • 更改 iOS 中禁用的栏按钮项目的颜色

    我需要在导航栏中显示我的应用程序的图标 为此 我将其添加为右栏按钮项目 我不希望它可点击 我只需要那里的图标 所以我将其设置为禁用 问题是图标显示为灰色 而不是绿色 有没有办法禁用此按钮但又保留其原始颜色 尝试这个 let barButto
  • wcf 测试客户端不支持此操作,因为它使用类型 system.object[]

    您好 在运行我的 wcf 服务时 出现错误 wcf 测试客户端不支持此操作 因为它使用类型 system object 我正在尝试检索正在运行的进程列表 ServiceBehavior InstanceContextMode Instanc
  • Windows UDP 套接字:recvfrom() 失败并出现错误 10054

    大家好 我正在尝试使用 Windows 套接字发送和接收 UDP 数据包 在 C 中 它一直运行良好 直到三天前程序停止正常运行 总结一下情况 当在我的套接字上调用 WSAPoll 时 即使没有启动服务器 它也总是返回用所有可能的 reve