【问题标题】:Receiving and returning a packet after the function has ended函数结束后接收和返回数据包
【发布时间】:2014-03-25 09:43:41
【问题描述】:

我有两个功能。一个人向一个端口号发送一个 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)

我非常感谢任何帮助。

【问题讨论】:

    标签: python sockets udp packet


    【解决方案1】:

    我想我知道会发生什么。

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

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

    假设端口 1010 会产生回复。但是让我们假设服务器需要一整秒的时间来回复。由于超时时间不到一秒,因此您的应用程序已经在 1010 之后取得了很好的进展。当回复到达时,您的应用程序已经在,例如,1020。现在看起来收到的包是向 1020 发送东西的结果。

    可能的方法

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

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

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

    然后您可以使用例如两个线程。一个发送包裹,一个接收答案。你保留一个将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() 将永远运行,但它显示了基本思想。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 2018-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多