问题场景:服务器有多个网卡,分别绑定了地址 A 、地址 B 和地址 C,当客户端连接请求过来的时候,如何知道是从哪个 IP 地址请求过来的?
解决方案:服务端 accept 客户端的连接后,对这个新接受的 socket 进行 getsockname 就可以了。
示例代码:
1 2 3 4 5 6 7 |
fd = accept(listen_fd, (struct sockaddr *)&addr, &addr_len); if (fd < 0) { // xxxx } else { getsockname(fd, (struct sockaddr *)&fd_addr, &addr_len); // fd_addr 此时就保存了客户端连接过来的目的地址 } |
假设客户端地址是 1.1.1.1,通过 connect(2.2.2.2) 过来,此时拿到的就是 2.2.2.2 这个地址。
拓展
getsockname 和 getpeername:
- getsockname:获取当前 socket 绑定的地址,执行 bind 后可以获取当前 socket 的地址信息,执行 accept 后可以获取对端连入的地址。
- getpeername:获取对端 socket 绑定的地址,connect 或者 accept 后可以得到对方的地址。
评论