无法在我的服务器上获取已连接客户端的公共 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-ForX-Original-Forwarded-ForX-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 地址?

配置好了DHCP服务器,但是却无法自动获取IP

如何使用 express 框架通过 node.js 获取远程客户端的本地 IP 地址?

由于 nginx 反向代理,无法获取用户 ip

如何控制对等端的套接字[TCP打孔]

Java获取客户端IP