(运行在VS2017,Win7 x64上)
我对SO_REUSEADDR和SO_EXCLUSIVEADDRUSE的观点感到困惑。是的,我读过MSDN文档,但我显然不明白。
我在两个独立的进程中有以下简单的代码。正如预期的那样,因为我在两个套接字上启用了SO_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_REUSEADDR就没有必要了--如果我不希望任何人严格地绑定到我的端口,那么在这个过程中就不会启用SO_REUSEADDR了吗?
我唯一能看到的区别是,如果在第一个进程中启用SO_EXCLUSIVEADDRUSE,然后在第二个进程中尝试绑定,则第二个绑定将失败。
( a)如果在第二个进程中不启用WSAEADDRINUSE (如果我不启用SO_REUSEADDR )
( b)在第二个进程中,如果我WSAEACCES do启用SO_REUSEADDR
因此,我尝试在第一个进程中同时启用SO_EXCLUSIVEADDRUSE和SO_REUSEADDR,但是发现我尝试的第二个进程在WSAEINVAL中失败了。
还请注意,我读过这过去的问题,但这并不是我所看到的:它说明
带有SO_REUSEADDR的套接字始终可以绑定到与已绑定的套接字完全相同的源地址和端口,即使其他套接字在绑定时没有设置此选项。
现在,如果是这样的话,那么我肯定看到了对SO_EXCLUSIVEADDRUSE的需求。
我很确定我做错了什么,但我看不见,有人能澄清一下吗?
发布于 2018-04-05 19:06:57
正如文档中所述,SO_EXCLUSIVEADDRUSE可以在NT4 SP4上使用;在此之前,只有才有 SO_REUSEADDR。因此,两者的存在都有历史原因。
我认为SO_REUSEADDR是为了共享一个地址(这只对UDP组播非常有用)。对于单播或TCP,它实际上做得不多,因为bahaviour对于两个套接字都是不确定的)。
SO_EXCLUSIVEADDRUSE是一种安全措施,以避免我的(服务器)应用程序的通信被随后绑定到同一个IP/端口而被劫持/变得无用。
在我看来,UDP多个程序需要SO_REUSEADDR,需要SO_EXCLUSIVEADDRUSE作为服务器应用程序的安全措施。
https://stackoverflow.com/questions/49673200
复制相似问题