要使 Winsock 程序仅接受来自特定 IP 地址的连接,请使用以下条件接受机制WSAAccept() http://msdn.microsoft.com/en-us/library/ms741513%28VS.85%29.aspx。首先,启用该功能:
SOCKET sd = socket(...);
listen(sd, ...);
DWORD nTrue = 1;
setsockopt(sd, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char*)&nTrue, sizeof(nTrue));
然后,修改您的接受调用,使其看起来像这样:
sockaddr_in sin;
WSAAccept(sd, (sockaddr*)&sin, sizeof(sin), ConditionalAcceptChecker, 0);
ConditionalAcceptChecker
是您编写的函数,它决定堆栈是否接受或拒绝连接。如果拒绝,远程对等方将收到 TCP RST 数据包,因此它知道它被拒绝。
如果您希望网络堆栈静默地丢弃来自其他地址的连接尝试而不通知远程对等方,则必须在比 Winsock 更低的级别执行此操作。在 Vista 或 Windows Server 2008 及更高版本上,此命令将修改防火墙规则以达到您想要的效果:
netsh advfirewall firewall add rule name=MyProtocol dir=in remoteip=1.2.3.4
localport=1234 protocol=tcp action=allow
这是一个命令,由于 Stack Overflow 上的格式限制而被分割。
它表示允许 IP 1.2.3.4 的远程计算机连接到本机上的 TCP 端口 1234。如果您在默认模式下启用了防火墙,该模式会拒绝未明确允许的流量,则来自所有其他计算机的连接尝试将被丢弃。
在旧版本的 Windows 上,回到 XP,有不同的“netsh 防火墙”语法来获得相同的效果。只需在命令提示符下键入“netsh firewall”即可开始浏览其内置帮助。