Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 所以你是唯一的,所以你是唯一的_Sockets_Network Programming_Winsock_Winsock2 - Fatal编程技术网

Sockets 所以你是唯一的,所以你是唯一的

Sockets 所以你是唯一的,所以你是唯一的,sockets,network-programming,winsock,winsock2,Sockets,Network Programming,Winsock,Winsock2,(在VS2017、Win7 x64上运行) 我对SO_REUSEADDR和SO_exclusiveeaddruse的观点感到困惑。是的,我读过这本书,但我显然不明白 我在两个单独的进程中有以下简单代码。正如预期的那样,因为我在两个套接字上都启用了SO\u REUSEADDR,所以第二个进程的绑定成功了如果我没有在这些套接字中的任何一个上启用此功能,则第二次绑定将不会成功 #define PORT 5150 SOCKET sockListen; if ((sockListen = WSASocke

(在VS2017、Win7 x64上运行)

我对
SO_REUSEADDR
SO_exclusiveeaddruse
的观点感到困惑。是的,我读过这本书,但我显然不明白

我在两个单独的进程中有以下简单代码。正如预期的那样,因为我在两个套接字上都启用了
SO\u REUSEADDR
,所以第二个进程的绑定成功了如果我没有在这些套接字中的任何一个上启用此功能,则第二次绑定将不会成功

#define PORT 5150
SOCKET sockListen;
if ((sockListen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
    printf("WSASocket() failed with error %d\n", WSAGetLastError());
    return 1;
}

int optval = 1;
if (setsockopt(sockListen, SOL_SOCKET, `SO_REUSEADDR`, (char*)&optval, sizeof(optval)) == -1)
    return -1;

SOCKADDR_IN InternetAddr;
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = inet_addr("10.15.20.97");
InternetAddr.sin_port = htons(PORT);

if (::bind(sockListen, (PSOCKADDR)&InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
    printf("bind() failed with error %d\n", WSAGetLastError());
    return 1;
}
因此,不必为两个套接字启用
So\u REUSEADDR
会使
So\u exclusiveeaddruse
变得不必要吗?如果我不希望任何人强制绑定到我的端口,我只是在该过程中不启用
So\u REUSEADDR

我能看到的唯一区别是,如果我在第一个进程中启用
SO_exclusiveeaddruse
,然后在第二个进程中尝试绑定,那么第二个绑定将失败

a)
WSAEADDRINUSE
如果我不启用
则在第二个过程中重新使用EADDR

b)
WSAEACCES
如果我do启用
SO\u在第二个过程中重新使用eaddr

因此,我尝试在第一个过程中同时启用
So_exclusiveadedruse
So_REUSEADDR
,但发现我第二次尝试的任何一个都失败了
WSAEINVAL

还要注意的是,我已经阅读了过去的问题,但它所说的并不是我所看到的:它表明

具有SO_REUSEADDR的套接字始终可以绑定到完全相同的源 地址和端口作为已绑定的套接字,即使另一个套接字 绑定时未设置此选项

如果是这样的话,那么我可以肯定地看到需要
SO\u exclusiveeaddruse


我很确定我做错了什么,但我看不出来;有人能澄清一下吗?

如文件中所述,因此在Windows NT4 SP4上提供了独家EADDRUSE;在此之前,只有
那么多。因此,两者的存在有(也有)历史原因

我认为sou_REUSEADDR是为了共享一个地址(这只对UDP多播真正有用。对于单播或TCP,它实际上没有多大作用,因为对于两个套接字来说,bahaviour都是不确定的)

因此,_exclusioneaddruse是一种安全措施,可以避免我的(服务器)应用程序的流量被稍后绑定到同一IP/端口时被劫持/变得无用


在我看来,对于UDP多播,您需要SO_REUSEADDR,并且您需要SO_ExclusiveADRUSE作为服务器应用程序的安全措施。

谢谢。但是我仍然不明白
的意义,所以_排他性eaddruse
;如果我没有在我的服务器中设置
SO\u REUSEADDR
,任何恶意应用程序都不可能劫持我的流量(如上所示),即使它本身设置了
SO\u REUSEADDR
。因此,我不需要
所以\u排他性的EADDRUSE
?如果不设置
SO\u reusioneaddr
,那么,
SO\u reusioneaddr
给了我什么?从操作上说,你是对的,但正如文档中提到的,“独占”是后来引入的,而且在最重要的方面,他们进行了更改以提高安全性。因此,您可以混合使用一些历史资料(更不用说与UNIX/Linux套接字的区别了)。此外,我发现使用“独占”明显增加了代码可读性…如果只是不在服务器中设置
SO\u exclusiveadruse
以防止恶意客户端绑定到同一端口,为什么要引入
SO\u exclusiveadruse
?我能想到的唯一一件事是,在早期版本中,不设置
SO\u REUSEADDR
并不能阻止恶意客户端-因此引入
SO\u exclusiveeaddruse
来解决这一问题,在较新的版本中,
SO_reusiveddr
的行为已经改变,因此不在服务器中设置它可以防止恶意客户端绑定,因此没有必要使用
SO_exclusiveedruse
。但是我在任何地方都找不到这方面的文档,你认为呢?MSDN(XP和更早版本)的第二个表中提到了这一点:如果第一个绑定在没有任何选项(“默认”)的情况下完成,则第二个绑定(带有SO_REUSEADDR)将成功。非常好。我没有发现第二个表适用于XP和更早版本(因此我不会在我的Win7框中看到这种行为),第三个表适用于Server2003和更高版本。谢谢