为什么我无法在Windows套接字上禁用MTU发现? IP_PMTUDISC_DONT无法设置

时间:2018-04-23 13:43:05

标签: c windows sockets udp

我试图在Windows上构建uftp。它是UDP传输客户端/服务器。

我最终能够使用OpenSSL链接制作静态二进制文件。但是我仍然遇到一位代码问题。它无法在套接字上设置IP_PMTUDISC_DONT标志。

当我运行代码Windows错误时:

> uftpd.exe -D C:\xfertest\ -p 1044 -d -T c:\tmp

Error disabling MTU discovery: (10042) An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call.
Error leaving multicast group: (10038) An operation was attempted on something that is not a socket.

这是尝试在client_init.c中设置套接字上的标志的代码:

#ifdef IP_MTU_DISCOVER
{
    int mtuflag = IP_PMTUDISC_DONT;
    if (setsockopt(listener, IPPROTO_IP, IP_MTU_DISCOVER, &mtuflag, sizeof(mtuflag)) == SOCKET_ERROR) {
        sockerror(0, 0, 0, "Error disabling MTU discovery");
        closesocket(listener);
        exit(ERR_SOCKET);
    }
}
#endif

这是基于VS2017社区版的Windows Server 2016构建的。

我已经尝试过测试那些不包含此标志的版本,但它们似乎有更糟糕的性能(大量的NAK),如果这会造成碎片,这可能并不令人意外。

任何人都可以想到为什么我可以设置setsockopt()吗?侦听器确实是由listener = socket(family, SOCK_DGRAM, 0)在同一文件中创建的套接字。我在互联网上看到其他反馈,声称其中一些API可能随着时间的推移而发生变化。我将看看我是否可以在早期的VS和OS版本上构建,但我希望有人能够在此之前找到解决方案的明确路径。

1 个答案:

答案 0 :(得分:1)

在Windows Server 2016中,IP_MTU_DISCOVER的支持根本就不存在。

IP_MTU_DISCOVER在Windows 10 build 15002中的UDP套接字的WSL(Windows子系统Linux)中实现(请参阅WSL问题#69#170#717和{ {3}}在GitHub上:

#720

  

实施IP_MTU_DISCOVER INET套接字选项(GH#720,717,170,69)

IP_MTU_DISCOVER在WSL中实现,用于Windows 10内部版本16215中的TCP套接字(请参阅GitHub上的WSL问题https://docs.microsoft.com/en-us/windows/wsl/release-notes#build-15002#1639#2115):

#2205

  

为TCP套接字添加了对IP_MTU_DISCOVER的支持。 [GH 1639,2115,2205]

仅仅因为预处理器具有#define的{​​{1}}值并不能保证目标操作系统您的目标操作系统代码最终在实际支持IP_MTU_DISCOVER上运行。您需要运行代码并忽略来自IP_MTU_DISCOVER的{​​{1}}错误,例如:

WSAENOPROTOOPT