【发布时间】:2017-08-29 08:55:21
【问题描述】:
服务器有多个接口。服务器绑定到 0.0.0.0,这意味着它正在侦听它拥有的所有接口。因此,客户端可以使用这些服务器 IP 中的任何一个进行连接。 那么,在服务器端如何获取客户端连接的IP。
【问题讨论】:
-
@UlugToprak ,我想要服务器的 IP 而不是客户端的 IP。
-
措辞不清楚,我删除了重复的标志。
服务器有多个接口。服务器绑定到 0.0.0.0,这意味着它正在侦听它拥有的所有接口。因此,客户端可以使用这些服务器 IP 中的任何一个进行连接。 那么,在服务器端如何获取客户端连接的IP。
【问题讨论】:
在accept()返回的套接字上使用getsockname(),它将绑定到您的服务器用来与接受的客户端通信的本地地址。
NAME
getsockname — get socket name
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
int
getsockname(int s, struct sockaddr * restrict name,
socklen_t * restrict namelen);
DESCRIPTION
The getsockname() system call returns the current name for the specified
socket. The namelen argument should be initialized to indicate the
amount of space pointed to by name. On return it contains the actual
size of the name returned (in bytes).
【讨论】:
getsockname()返回客户端用来连接服务端的地址,可以是服务端的任意一个IP地址,也就是问题所在:哪个。这里没有矛盾。客户端的自己的地址,“服务器用于与客户端通信”,由服务器上的getpeername()返回。
getsockname() 是套接字的 LOCAL 地址,而 getpeername() 是 REMOTE 地址。在服务器端,本地地址是客户端connected 的监听地址,远程地址是客户端connected 的地址。因此,“客户端用于与此服务器通信的地址”是指服务器的本地地址,而“服务器用于与客户端通信的地址 " 指的是客户端的远程地址。
此信息可通过getsockname() 呼叫获得。在服务器端调用时,它提供服务器accept客户端所在的本地服务器地址。
请注意,这受到称为“弱端系统模型”的深奥事物的影响,这实质上意味着接收连接的本地接口不一定对应于客户端使用的 IP 地址(想想会发生什么当代理/路由器位于客户端和服务器之间时)。在这种情况下,您将无法获得客户端实际connected 到的实际 IP(除非客户端以数据包的形式将其发送到服务器),只有接受客户端的服务器上的 IP。
【讨论】: