在功能结束后接收并返回数据包



我有两个函数。一个向端口号发送UDP数据包,如果得到响应,则返回端口号。第二个循环通过调用第一个函数的地址,重复递增端口号。当返回端口号时,它停止。我基本上是在滥发一个IP来查找正在使用的端口号。

所有这些都能在很长的时间内正常工作,但我正在努力加快发送测试包的速度。例如,即使垃圾邮件端口功能正在发送到27022,我也可能从端口27018收到一个数据包。然后它错误地报告27022是要使用的端口。即使当我返回第一个函数返回的数据包信息时,也会发生这种情况,因为你无法说出最初使用的参数。

def check_port(s, serverip, serverport):  
payload = "ffffffff54536f7572636520456e67696e6520517565727900".decode('hex')
s.sendto(payload, (serverip, serverport))
while 1:
try:
s.settimeout(0.1) # time to wait for response
d = s.recvfrom(1400)
data = d[0]
addr = d[1]
if len(data) > 1:
break
except socket.error:
return False
return addr[1]
def spam_ports(serverip): 
s = serverComms.port_config()
start_highport = 27015
end_highport = 28015
start_lowport = 2299
end_lowport = 4000
port = start_highport
while check_port(s,serverip, port) == False:
port += 1
if port == end_highport:
port = start_lowport
if port == end_lowport:
return 'no query ports found in range'
else:
return check_port(s,serverip, port)

我真的很感谢你的帮助。

我想我知道会发生什么。

服务器需要一些时间才能回复。如果延迟时间短于此,则您的应用程序将变得混乱。让我解释一下:

您将包裹发送到端口1000、1001、1002。。。

假设端口1010产生一个应答。但假设服务器需要整整一秒钟的时间来回复。您的应用程序在1010之前进展良好,因为超时时间不到一秒钟。当回复到达时,你的申请已经在1020了。现在看来,接收到的包是向1020发送一些东西的结果。

可能的方法

你需要的是一种方法来知道收到的回复属于哪个端口。这里变得棘手:

每个包都有一个源端口和一个目标端口。随着包的发送,目标端口会递增。源端口可能是任意分配的。当服务器回答时,它将发送一个具有任意源端口的包,并且目标端口等于包的源端口。

您可以查看文档,了解如何控制要发送的包的源端口。这样,你就可以确保每个发送的包都有一个不同的源端口。这可以唯一地标识每个包。现在你可以使用回复的目的地端口来知道它属于哪个。

然后可以使用,例如,两个线程。一个发送包裹,一个接收答案。您保留了一个dict,它将my_source_port映射到server_port。发送方填写dict,接收方读取。您可以让发送方尽可能快地发送,现在需要超时。一旦发送器完成,你就给接收器线程一秒钟左右的时间来赶上。

port_map = {}
active_ports = []
def send(min, max):
for dest_port in range(min,max):
src_port = get_free_port()
port_map[src_port] = dest_port
send_package(src_port, dest_port, 'somedata')
def recv():
while True:
src_port, dest_port, data = receive_package()
port = port_map[dest_port]
active_ports.append(port)

这不是一个可行的例子,只是一个基本的想法。方法不以这种形式存在,线程同步丢失,recv()将永远运行,但它展示了基本思想。

您可能需要为发送的每个包创建一个套接字。

最新更新