【发布时间】:2018-04-05 13:07:50
【问题描述】:
(运行于VS2017,Win7 x64)
我对@987654323@ 和SO_EXCLUSIVEADDRUSE 的观点感到困惑。是的,我已经阅读了MSDN documentation,但我显然不明白。
我在两个单独的进程中有以下简单代码。正如预期的那样,因为我在两个套接字上都启用了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_EXCLUSIVEADDRUSE - 如果我不想让任何人强行绑定到我的端口,我只是不启用SO_REUSEADDR 在那个过程中?
我能看到的唯一区别是,如果我在第一个进程中启用 SO_EXCLUSIVEADDRUSE,然后在第二个进程中尝试绑定,那么第二个绑定将失败
a) WSAEADDRINUSE 如果我不在第二个进程中启用 SO_REUSEADDR
b) WSAEACCES 如果我在第二个进程中做启用SO_REUSEADDR
所以我尝试在第一个进程中同时启用SO_EXCLUSIVEADDRUSE 和SO_REUSEADDR,但发现无论我第二次尝试的哪个都以WSAEINVAL 失败。
另请注意,我已阅读 this 过去的问题,但上面所说的不是我所看到的:它说明了
具有 SO_REUSEADDR 的套接字始终可以绑定到完全相同的源 地址和端口作为已经绑定的套接字,即使另一个套接字 绑定时没有设置这个选项
如果是这样的话,那么我绝对可以看到SO_EXCLUSIVEADDRUSE 的必要性。
我很确定我做错了什么,但我看不到;有人可以澄清一下吗?
【问题讨论】:
标签: sockets network-programming winsock winsock2