VC 为啥我获取客户端ip地址总是:204.204.204.204
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC 为啥我获取客户端ip地址总是:204.204.204.204相关的知识,希望对你有一定的参考价值。
Socket接受连接时可以用一个Sockaddr_in结构来接收发送方的地址,例子如下: sockaddr_in *addr=new sockaddr_in; CString address; Accept(*Connect,(sockaddr *)addr,&len); address=inet_ntoa(addr->sin_addr); 此时address中就是对方的IP。 我用MessageBox(address); 显示总是:204.204.204.204 不知道是为什么? 用getpeername(.......)函数得到的结果也是一样~! 先谢了~!!!
参考技术A 简单的Winsock
应用程式设计
struct
sockaddr_in
sa;
int
salen
=
sizeof(sa);
getsockname(
sd,
(struct
sockaddr
FAR
*)&sa,
&salen
)
【如何知道和我们的
Socket
连接的对方是谁】
连接的
Socket
是有两端的,所以相对於
getsockname()
函式,Winsock
也提
供了一个
getpeername()
函式,来让我们获得与我们连接的对方的
IP
位址与
port
number。
◎
getpeername():获取连接成功之
Socket
的对方
IP
位址及
port
number。
格
式:
int
PASCAL
FAR
getpeername(
SOCKET
s,
struct
sockaddr
FAR
*name,
int
FAR
*namelen
);
参
数:
s
Socket
的识别码
name
储存与此
Socket
连接的对方
IP
位址的暂存区
namelen
name
的长度
传回值:
成功
-
0
失败
-
SOCKET_ERROR
(呼叫
WSAGetLastError()
可得知原因)
说明:
此函式可用来取得已连接成功的
Socket
的彼端之位址资料。
呼叫的方式如下:
struct
sockaddr_in
sa;
int
salen
=
sizeof(sa);
getpeername(
sd,
(struct
sockaddr
FAR
*)&sa,
&salen
)
现在我们仍然利用
WinKing
来当我们的
Winsock
Stack,并利用它所提供的
工具来观察
Sockets
的连结及资料是否正确。
由图
1,我们可以由
WinKing
的视窗看到我们设定这台主机的名称是
「vincent」,IP
位址是
「140.92.61.24」。我们并利用两个
hello
程式,一
个当
成
Client
(画面右边打开者),一个当成
Server
(画面左边最小化者)。Se
rver
所用的
port
number
是
「7016」;
Client
并没有呼叫
bind()
来指定
port
number,而是呼叫
connect()
时由系统指定。
我们呼叫
gethostname(),得到的答案是
「vincent」;而
Client
呼叫
getsockname()
得到自己的
IP
位址是
「140.92.61.24」,port
number
是
「
2110」
(笔者以前曾提过,由系统主动指定的
port
number
会介於
1024
到
5000
间)
;
再呼叫
getpeername()
得到与
Client
连接的
Server
端
IP
位址是
「140.92
.61.24」
(因为我们的
Client
和
Server
都在同一台主机),port
number
是
「7016」
。果
然没错!(由
WinKing
的
Sockets'
Status
视窗亦可观察到相互连接的
Socke
ts
资
料,与我们呼叫函式所得结果相同)
为啥服务器无法获取客户端 MAC 地址,例如客户端 IP?
【中文标题】为啥服务器无法获取客户端 MAC 地址,例如客户端 IP?【英文标题】:Why can't the server get the client MAC address, like the client IP?为什么服务器无法获取客户端 MAC 地址,例如客户端 IP? 【发布时间】:2011-02-20 17:38:56 【问题描述】:据我所知,数据包经过的所有 MAC 地址都在数据包中。这是因为每个进入特定路径的数据包也应该以相似的路径返回。那么,如果服务器的路由器知道客户端的mac地址(全部),为什么服务器页面(如aspx)不能有这个信息?
请解释一下。 (不要只是告诉我我错了)。
如果我理解正确,客户端会发送一个包含其 MAC 地址的数据包。当数据包通过代理(如客户端路由器)时,代理的地址也被添加到数据包中。等等。
这是来自***的关于 TCP/IP 数据线层的 sn-p:http://en.wikipedia.org/wiki/TCP/IP_model#Data_Link_Layer
数据链路层用于移动 互联网层之间的数据包 两个不同主机的接口 同一个链接。的过程 发送和接收数据包 给定的链接可以同时控制 软件设备驱动程序 网卡,以及固件 或专用芯片组。这些将 执行数据链接功能,例如 添加一个数据包头来准备它 传输,那么实际上 通过物理传输帧 中等的。 TCP/IP 模型包括 翻译规范 中使用的网络寻址方法 互联网协议到数据链路 寻址,例如媒体访问 控制 (MAC),但所有其他 低于该水平的方面是 隐含假设存在于 链路层,但不明确 已定义。
【问题讨论】:
您只是想知道,还是有实际问题要解决? 我想从 Web 应用程序中获取客户端 MAC 地址。 是的,如果客户端和 Web 应用程序服务器在同一个网络中,则可以,在某些小型网络中可能是这样。 【参考方案1】:在了解为什么服务器无法访问其客户端的 MAC 地址之前,让我们先了解一下数据包是如何在网络中传输的。
案例一:
如果应用程序只知道域名,目标 IP 地址将为网络应用程序所知或从 DNS 服务器获得。 然后主机将目标IP地址与自己的IP地址和子网掩码进行比较。如果目标主机在源主机的网络中,源主机将向线路发送一个 ARP 请求,询问“谁拥有那个 IP 地址?”目标主机将回复其 MAC 地址。
案例 2:(互联网上通常是这种情况)
如果目标主机不在源主机的网络中,假设我们在浏览 Google.com 时,DNS 会将名称解析为 IP。源主机将发送一个 ARP 请求,询问“谁有我的默认网关的 IP 地址?”。在这种情况下,由于它在我们的网络之外,我们将向我们的默认网关发送 ARP 请求(默认网关是使用互联网协议套件的计算机网络中的节点,用作到其他网络的转发主机(路由器)), DG 用它的 MAC 回复。您使用 Google 的目标 IP 和我们 DG 的目标 MAC 发送数据包。当 DG 收到这个带有自己的目标 MAC 和 IP Header 中的其他一些目标 IP 地址的帧时,它知道该数据包不是发往自己的,而只是遍历。然后 google 的 ip 查找,然后是下一跳的 ARP 等继续..
所以你看,进行物理寻址的数据链路层从不知道目的地的 MAC 地址,它只知道下一个 HOP(路由器)的 MAC 地址。下一个路由器的MAC地址是通过ARP请求获得的。那么接收方如何知道其发送方的 MAC 地址。好吧,它从来不知道,也不能,因为每次路由器收到数据包时,它都会在源 MAC 地址字段中添加自己的 MAC 地址,或者说它用自己的 MAC 地址替换它。因此,服务器将永远无法知道其接收器的 MAC 地址,因为它从未出现在数据包中。它只是剩下的IP地址。
【讨论】:
【参考方案2】:在 IPv6 中,如果将 IPv6 地址编码为 64 位 the host address,则可能实际上会获取计算机的 MAC 地址。
另请参阅超级用户上的How to avoid exposing my MAC address when using IPv6?。
【讨论】:
【参考方案3】:它是保留的源和目标 IP 地址。网络间的思想基本上是基于跳到跳的传递。中间路由器/主机只理解 MAC 地址。据我所知,路由表应该理解机器地址。
如果 MAC 地址可以在数据包的整个传输过程中保留;这意味着不需要发明互联网协议地址。而且所有的互联网都只会使用 MAC 地址 :-)
只有当服务器和客户端都位于同一个本地网络上时(两台主机都通过一些 L1 媒体连接),您才能实现您想要的。
话虽如此,您的应用程序看起来有点像 Web 服务器,它告诉我它不必在同一个网络上。
如果你想在接收主机上获得源主机的 MAC 地址;考虑将其作为有效负载发送?
加法:
世界各地的网络不必是同一类型(即以太网、帧中继等)。网络层为我们提供了路由的灵活性,没有区分底层(数据链路层)或者我应该说底层 L1 技术。简而言之,IP 将为我们提供网络间和数据链路层(MAC 地址进入图片)将在微观级别(即本地网络)处理通信。这就是 Mac 和 IP 地址共存的合理原因! :-)
【讨论】:
问题是为什么不可能?这就是我想要理解的。 @Stacker,我刚刚在上面添加了一些内容以响应您的查询【参考方案4】:简单的区别是:IP 地址是端到端地址(当然是在 IP 数据包中),而 MAC 地址只能逐跳使用。 此外,底层的 MAC 协议可能会在每一跳发生变化,而客户端不知道,因此客户端甚至可能无法了解其 IP 数据包沿途的所有地址。
【讨论】:
【参考方案5】:IP 堆栈和物理堆栈之间的关系颠倒了。 MAC 地址在包装 IP 信息的部分中,而不是相反。因此,当我从我的计算机向您的计算机发送一些东西时,我的 LAN(在这种情况下为以太网)中的物理网段会环绕 IP 内容并包括我的 MAC。然后,路由器提取 IP 信息,并在此过程中使用其自己的 MAC 将其向前和向上(在本例中再次通过以太网)传递到我的 DSL 调制解调器。 DSL 调制解调器解开 IP 内容,并使用它使用的任何协议(当时不知道也不关心)将其发送到电话线上......好吧,你明白了。每个物理链路跳都使用底层物理层为本地传输附加的任何额外信息来封装和解封装 IP 信息。
【讨论】:
所以,当我想给你发回一些东西时,我会将它发送到你的 IP 地址。但是您的计算机位于以太网后面,并且IP是您路由器的IP。那么你的路由器如何知道识别这个东西所属的正确计算机而不询问MAC地址的东西(数据包)? 路由器保留 IP 地址和相关 MAC 的记录。 (这是一个超级简单的概述,如果您想了解更多详细信息,我建议您选择一本关于 TCP/IP 网络的好书,然后翻到路由章节,以及 NAT 和其他此类内容。)【参考方案6】:实际上,存储在数据包中的 MAC 地址在数据包传输的每一跳中都会更改。
MAC 是媒体访问控制的简写,媒体是指本地 通信媒体。虽然源和目标 IP 地址在整个旅程中保持不变(并用于长途路由决策),但源和目标 MAC 地址仅指示下一跳。
因此,存储在您的服务器接收的数据包中的 MAC 地址应该是您的接入点路由器或您的提供商设备的 MAC 地址。
您可能想看看 OSI 层模型 和 encapsulation。
【讨论】:
【参考方案7】:您考虑的是服务器 LAN 和客户端 LAN 之间的直接连接,而这并不是互联网的工作方式。两个 LAN 之间可能有任意数量的跃点 - 顺便说一下,任何一个 LAN 都使用 MAC 之类的东西没有任何限制,因此“MAC 地址”不会放在 IP 数据包中。 “A MAC”仅在 LAN 中有意义(实际上,只有最低层使用 MAC 之类的东西;-),并且通过 ARP 和 RARP 协议发现/宣布(不得到路由;-)。
【讨论】:
【参考方案8】:您不能 - 除非客户端在您的服务器本地。如果是这样,您可以尝试对其进行 arp-ping 并以这种方式获取客户端的 mac 地址。
【讨论】:
【参考方案9】:没有“服务器的路由器”。数据包可能从许多路由器到达服务器。
没有“客户端的路由器”。数据包可能从客户端发送到多个路由器。
唯一可以看到 MAC 地址的设备是同一 LAN 上的设备 - 可能只有同一电缆段上的设备。
顺便说一句,如果客户端位于代理服务器的另一端,服务器也无法获取客户端 IP 地址。
【讨论】:
如果我理解正确,客户端会发送一个包含其 MAC 地址的数据包。当数据包通过代理(如客户端路由器)时,代理的地址也会添加到数据包中,依此类推。 出于正确的目的,这很重要,但实际上,服务器看到的 MAC 地址可能来自同一家庭 --yes/no?我知道可以从 Win32 套接字中挖掘物理地址信息,但是,我怀疑这些信息是否可以通过服务器提供的 ISAPI 或类似接口访问,我认为这是一个 IIS。 服务器看到的MAC地址将是客户端到服务器路径上最后一个路由器的一个端口的MAC地址。来自同一客户端的下一个数据包可能从同一路由器上的不同端口接收,或者完全从不同路由器接收。这意味着每个数据包可能有不同的 MAC 地址。这些地址与家庭无关——MAC地址被烧录到计算机的网卡中。以上是关于VC 为啥我获取客户端ip地址总是:204.204.204.204的主要内容,如果未能解决你的问题,请参考以下文章
路由器地址池有啥作用?我的IP地址不在地址池内,为啥也能正常上网?