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 的相关文章

  • json.net自定义jobject反序列化

    我正在尝试使用 JsonConvert DeserializeObject string 将字符串反序列化为可与动态一起使用的 jobject 来动态访问 json 文档 但是我想避免知道文档的大小写 以便我可以输入 dynamic doc
  • C++ 长 switch 语句还是用地图查找?

    在我的 C 应用程序中 我有一些值充当代表其他值的代码 为了翻译代码 我一直在争论使用 switch 语句还是 stl 映射 开关看起来像这样 int code int value switch code case 1 value 10 b
  • 将完整模板参数值映射到原始类型

    我想将数字映射到类型 在这个例子中 我将创建一个函数 将 sizeof 结果映射到有符号的原始类型 我想知道是否有更好的方法来完成我在现代 C 中所做的事情 即采用模板化值并将其转换为类型 现在 这可以将大小转换为已知类型 但我似乎无法在标
  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 使用 C# 和 wpf 创建类似 Dock 的应用程序

    我需要创建一个与我们购买笔记本电脑时获得的应用程序类似的应用程序 仅当鼠标指针到达窗口顶部时它才可见 那么我怎样才能使用 C 4 0 来做到这一点呢 http www notebookcheck net uploads pics win2
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • ASP.NET MVC 路由:如何从 URL 中省略“索引”

    我有一个名为 StuffController 的控制器 具有无参数索引操作 我希望从表单中的 URL 调用此操作mysite com stuff 我的控制器定义为 public class StuffController BaseContr
  • 在 C#.NET 中安全删除文件

    在我正在做的一个项目中 我想为用户提供 安全 删除文件的选项 例如 用随机位或 0 覆盖它 在 C NET 中是否有一种简单的方法可以做到这一点 效果如何 你可以调用系统内部删除 http technet microsoft com en
  • C++ 中 void(*)() 和 void(&)() 之间的区别[重复]

    这个问题在这里已经有答案了 在此示例代码中 func1是类型void int double and funky是类型void int double include
  • INotifyPropertyChanged 和 propertyName

    我一直不确定它的含义propertyName实施时INotifyPropertyChanged 所以一般来说你实现INotifyPropertyChanged as public class Data INotifyPropertyChan
  • 为什么匹配模板类上的部分类模板特化与没有模板匹配的另一个部分特化不明确?

    这个问题可能很难用标题中的句子来描述 但这里有一个最小的例子 include

随机推荐

  • 如何拍摄 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