无法在我的服务器上获取已连接客户端的公共 IP
Posted
技术标签:
【中文标题】无法在我的服务器上获取已连接客户端的公共 IP【英文标题】:Can't get the public IP of a connected client on my server 【发布时间】:2021-11-15 13:15:16 【问题描述】:我有一个用 Python 编写的非常基本的服务器,如下所示:
import socket
from time import sleep
import requests
c = None #Client socket1
addr = None #Client address1
server_socket1 = socket.socket() #by default it is SOCK_STREAM (TCP) and has porotocal AF_INET (IPv4)
server_socket1.bind(('127.0.0.1',9999)) #server machine's ip and port on which it will send and recieve connections from
server_socket1.listen(2) #We will only accept two connections as of now , one for each client
print("Server started successfully!!!")
print("Waiting for connections...\n\n")
while (((c is None)and(addr is None))):
if((c is None) and (addr is None)):
c,addr = server_socket1.accept()
print("Intrusion detected at address 127.0.0.1:9999 ")
print("Client connected with ip address "+str(addr))
client_ip=str(addr)
while True:
msg = c.recv(4096)
if(msg!=None):
#print(msg)
headers, sep, body = msg.partition(b'\r\n\r\n')
headers = headers.decode('utf-8')
print(headers)
html_body = "<html><body><h1>You are not authorized to acces this Page!</p><br><p>3 more attemps and your ip will be jailed!</p></body></html>"
response_headers =
'Content-Type': 'text/html; encoding=utf8',
'Content-Length': len(html_body),
'Connection': 'close',
response_headers_raw = ''.join('%s: %s\r\n' % (k, v) for k, v in response_headers.items())
response_proto = 'HTTP/1.1'
response_status = '200'
response_status_text = 'OK' # this can be random
# sending all this stuff
r = '%s %s %s\r\n' % (response_proto, response_status, response_status_text)
c.sendall(r.encode())
c.sendall(response_headers_raw.encode())
c.sendall(b'\r\n') # to separate headers from body
c.send(html_body.encode(encoding="utf-8"))
然后我使用 ngrok 在网络上转发我的端口 9999。然后我执行服务器。
现在,当我通过手机连接到 ngrok 提供的链接时,我会从服务器获得响应,即单行 HTML 内容,如代码本身所示。
但是,c,addr = socket.accept()
应该返回已连接客户端的 IP。就我而言,我已经用我的手机连接到 ngrok,它应该使用我手机的公共 IP 来连接它,仍然在我的服务器端,它显示如下:
谁能告诉我我在这里做错了什么?
【问题讨论】:
listen(2)
没有完成“我们现在只接受两个连接”。那不是它的用途。而且您的代码只接受一个连接。而且您不需要连续两次测试相同的条件。您可以删除 while
循环内的 if
。
哦,是的,非常感谢您为listen() 部分清理内容。而对于条件测试部分,我从另一个项目中获取了这段代码,却忘记将其删除。也感谢您告知。
【参考方案1】:
您所看到的非常有意义,因为手机没有直接连接到您的服务器(不可能,因为您的服务器正在侦听 127.0.0.1
aka localhost,因此它只能接受来自同一台机器)。
手机连接到ngrok,然后ngrok连接到你的服务器。因此,您会看到 ngrok 连接到您的服务器的 IP。您的服务器根本无法获取电话的 IP,除非 ngrok 在发送到您的服务器的 HTTP 请求中包含电话的 IP,例如 X-Forwarded-For
、X-Original-Forwarded-For
、X-Real-IP
等请求标头,这对于代理发送很常见(但我在您的屏幕截图中没有看到,但它不完整)。
--------- --------- ----------
| phone | <-> | ngrok | <-> | server |
--------- --------- ----------
^ ^
| |
desired IP is here but you are getting IP from here
【讨论】:
嘿,非常感谢这个详细的回答。我对到底发生了什么感到非常困惑,但你消除了我的疑虑。您能否建议我,我应该怎么做才能捕获我手机的公共 IP? @PriyanshGupta 除非 ngrok 将电话的 IP 添加到它发送到您的服务器的请求中(您正在打印标头,您是否看到列出的电话 IP?),或者电话将自己的 IP 添加到请求它发送到 ngrok,那么您的服务器根本无法获取手机的 IP以上是关于无法在我的服务器上获取已连接客户端的公共 IP的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PHP 中获取已连接客户端的 MAC 和 IP 地址?