通过以下 C 代码快照,我了解到,bind()调用绑定到 的地址listfd是运行该服务器程序的本地计算机的逻辑地址。随后,服务器监听listfd同一台机器的套接字。
struct sockaddr_in serv_addr;
listfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(8000);
retval = bind(listfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listfd)
Run Code Online (Sandbox Code Playgroud)
我在coursera上了解到,bind()调用还允许您将套接字绑定到远程地址和端口。
我想了解这一点。
我的意思是,
listfd = socket(AF_INET, SOCK_STREAM, 0);
提供来自该程序运行的程序进程(本地计算机)的文件描述符。
我的问题:
如果bind()调用将此本地套接字绑定listfd到远程地址而不是INADDR_ANY,那么哪台机器实际上在监听?因为listfd是来自该程序运行的本地计算机的本地进程文件描述符表的条目,并且该套接字listfd正在绑定到远程计算机 IP 地址?我该如何解释?这在幕后是如何工作的?
你不能bind()到一个远程地址,至少不能在AF_INET家里。根据bind的手册页,你会得到一个EADDRNOTAVAIL错误,说你想要绑定的地址不是本地的。
编辑:bind() 可能适用于远程地址,但肯定不适用于家庭AF_INET。请注意,还有更多内容。可能有一些系列确实支持绑定到远程地址,可能是一些集群协议。即使没有,理论上bind()也可以对这些进行研究,以防某些协议出现,这完全有意义。
Edit2:正如thuovila指出的那样,实际上存在绑定远程地址的情况AF_INET。即IP_TRANSPARENT在绑定之前设置socket选项。ip(7) 的手册页告诉我们:
IP_TRANSPARENT (since Linux 2.6.24)
Setting this boolean option enables transparent proxying on
this socket. This socket option allows the calling
application to bind to a nonlocal IP address and operate both
as a client and a server with the foreign address as the local
endpoint. NOTE: this requires that routing be set up in a way
that packets going to the foreign address are routed through
the TProxy box (i.e., the system hosting the application that
employs the IP_TRANSPARENT socket option). Enabling this
socket option requires superuser privileges (the CAP_NET_ADMIN
capability).
TProxy redirection with the iptables TPROXY target also
requires that this option be set on the redirected socket.
Run Code Online (Sandbox Code Playgroud)
因此,通过大量额外的工作,您可以通过将本地套接字和远程套接字与该套接字选项集绑定在一起来构建透明代理(如果我理解正确的话)。