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

时间:2014-02-23 22:47:59

标签: python sockets udp packet

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

所有这些都适用于非常长的时间,但我正在努力加快我发送测试数据包的速度。例如,即使垃圾邮件端口功能发送到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)

我真的很感激任何帮助。

1 个答案:

答案 0 :(得分:0)

我想我知道会发生什么。

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

您将包发送到端口1000,1001,1002,...

假设端口1010产生回复。但我们假设服务器需要一整秒才能回复。由于超时时间少于一秒,您的应用程序已经进步了1010。到答复到达时,您的申请已经在1020.现在看来收到的包裹是向1020发送内容的结果。

可能的approch

您需要的是一种了解收到的回复属于哪个端口的方法。这里很棘手:

每个包都有一个源端口和一个目标端口。使用您发送的目标端口的包增加。源端口可能是任意分配的。当服务器应答时,它将发送一个包含任意源端口的包,目标端口等于包的源端口。

您可以做的是查看文档,看看如何控制您发送的软件包的源端口。这样,您可以确保每个发送的包具有不同的源端口。这将唯一标识每个包。现在,您可以使用回复的目标端口来了解它属于。

然后你可以使用两个线程。一个发送包,一个发送答案。你保留了一张将my_source_port映射到server_port的字典。发送者填写字典,接收者读取它。您可以让发件人尽可能快地发送,现在需要超时。一旦发送者完成,你给接收者线程一秒左右赶上。

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()将永远运行,但它显示了基本的想法。

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