从客户端查找选择哪个端口的最佳方法
Best way to find which port is selected from client-side
我的程序使用地址 ('0.0.0.0', 0)
随机选择一个端口服务器端,并将唯一的 code
发送到客户端,套接字试图连接到一个范围内的每个端口,并且检查相同的 code
以确认正确的服务器端口。
问题是遍历所有端口 (range(1024, 65336)
),即使使用 ThreadPool
,尝试连接到每个端口也非常慢。
这只是一个展示我正在尝试做的事情的例子。我的主程序通过互联网托管,而不是在本地主机上。
server.py
import socket
CODE = 'Code123' # just an example
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = ('0.0.0.0', 0)
server.bind(addr)
# Can see which port is assigned
print(server)
def start():
server.listen(5) # connect to 5 connection.
while True:
conn, addr = server.accept()
conn.send(CODE.encode('utf-8'))
print("Code Sent")
start()
cilent.py
import socket
from multiprocessing.pool import ThreadPool
code = 'Code123' # just an example
server = socket.gethostbyname(socket.gethostname())
port_left = 65336
found = False
def connect(port):
global port_left, code, server, found
if found: return
port_left -= 1
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((server, port))
if client.recv(len(code)).decode('utf-8') == code:
found = True
return client
else: client.close()
except Exception as e:
print(e, port_left)
return None
pool = ThreadPool(10)
values = [('c', i) for i in set(pool.map(connect, range(1024, 65336))) if i]
client = dict(values).get('c')
pool.close()
pool.join()
print(client)
有没有更好的方法来实现这个目标或提高我现有代码的性能?
nmap provides ways to do this. Here's the example code from this page:
import nmap
# take the range of ports to
# be scanned
begin = 75
end = 80
# assign the target ip to be scanned to
# a variable
target = '127.0.0.1'
# instantiate a PortScanner object
scanner = nmap.PortScanner()
for i in range(begin,end+1):
# scan the target port
res = scanner.scan(target,str(i))
# the result is a dictionary containing
# several information we only need to
# check if the port is opened or closed
# so we will access only that information
# in the dictionary
res = res['scan'][target]['tcp'][i]['state']
print(f'port {i} is {res}.')
输出:
port 75 is closed.
port 76 is closed.
port 77 is closed.
port 78 is closed.
port 79 is closed.
port 80 is open.
但是,我会说随机分配服务器端口是不切实际的,您最好只分配一个固定端口。
不是直接回答,但太长了无法发表评论。
这不是预期使用随机端口的方式。它们用于 FTP 协议中的数据连接方式(被动模式):
- 客户端在已知端口 (21) 上打开控制连接
- 它向服务器请求随机数据端口通过控制连接
- 它打开数据连接知道它的端口
应避免在随机端口上打开连接,因为如果服务器没有立即响应,客户端必须等待超时以决定服务器是否正忙。
因此,如果您想使用随机端口,我的建议是保留一个众所周知的端口,客户端将在该端口上获得真正的随机端口。
我的程序使用地址 ('0.0.0.0', 0)
随机选择一个端口服务器端,并将唯一的 code
发送到客户端,套接字试图连接到一个范围内的每个端口,并且检查相同的 code
以确认正确的服务器端口。
问题是遍历所有端口 (range(1024, 65336)
),即使使用 ThreadPool
,尝试连接到每个端口也非常慢。
这只是一个展示我正在尝试做的事情的例子。我的主程序通过互联网托管,而不是在本地主机上。
server.py
import socket
CODE = 'Code123' # just an example
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = ('0.0.0.0', 0)
server.bind(addr)
# Can see which port is assigned
print(server)
def start():
server.listen(5) # connect to 5 connection.
while True:
conn, addr = server.accept()
conn.send(CODE.encode('utf-8'))
print("Code Sent")
start()
cilent.py
import socket
from multiprocessing.pool import ThreadPool
code = 'Code123' # just an example
server = socket.gethostbyname(socket.gethostname())
port_left = 65336
found = False
def connect(port):
global port_left, code, server, found
if found: return
port_left -= 1
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((server, port))
if client.recv(len(code)).decode('utf-8') == code:
found = True
return client
else: client.close()
except Exception as e:
print(e, port_left)
return None
pool = ThreadPool(10)
values = [('c', i) for i in set(pool.map(connect, range(1024, 65336))) if i]
client = dict(values).get('c')
pool.close()
pool.join()
print(client)
有没有更好的方法来实现这个目标或提高我现有代码的性能?
nmap provides ways to do this. Here's the example code from this page:
import nmap
# take the range of ports to
# be scanned
begin = 75
end = 80
# assign the target ip to be scanned to
# a variable
target = '127.0.0.1'
# instantiate a PortScanner object
scanner = nmap.PortScanner()
for i in range(begin,end+1):
# scan the target port
res = scanner.scan(target,str(i))
# the result is a dictionary containing
# several information we only need to
# check if the port is opened or closed
# so we will access only that information
# in the dictionary
res = res['scan'][target]['tcp'][i]['state']
print(f'port {i} is {res}.')
输出:
port 75 is closed.
port 76 is closed.
port 77 is closed.
port 78 is closed.
port 79 is closed.
port 80 is open.
但是,我会说随机分配服务器端口是不切实际的,您最好只分配一个固定端口。
不是直接回答,但太长了无法发表评论。
这不是预期使用随机端口的方式。它们用于 FTP 协议中的数据连接方式(被动模式):
- 客户端在已知端口 (21) 上打开控制连接
- 它向服务器请求随机数据端口通过控制连接
- 它打开数据连接知道它的端口
应避免在随机端口上打开连接,因为如果服务器没有立即响应,客户端必须等待超时以决定服务器是否正忙。
因此,如果您想使用随机端口,我的建议是保留一个众所周知的端口,客户端将在该端口上获得真正的随机端口。