【问题标题】:Can a Server listens to a UDP messages without IP configured服务器可以在没有配置 IP 的情况下监听 UDP 消息吗
【发布时间】:2016-03-30 10:22:20
【问题描述】:

请看下面的python代码。 我创建了一个 Server 类来监听 10000 端口以接收 UDP 广播消息。

如果系统中配置了IP地址,则可以接收UDP广播消息。如果没有配置 ip 地址,则无法接收任何消息。

你能告诉我为什么吗?

import socket
import sys

class Server:

    class Handler:

        def handle(self, message):
            pass

        def __init__(self, serialNo):
            self.serialNo = serialNo

        def _setAddress(self, socket, message, address):
            self.message = message
            self.address = address
            self.socket = socket

        def send(self, message):
            self.socket.sendto(message, self.address)

        def getSerialNo(self):
            return self.serialNo

    def __init__(self, port, handler):
        self.ss = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        self.handler = handler

        try:
            self.ss.bind(('<broadcast>', port))
        except:
            self.ss.close()
            raise RuntimeError("Create socket error")
        self.ss.setblocking(1)

    def loop(self):
        while True:
            try:
                print "Listening for broadcast..."
                message, address = self.ss.recvfrom(8192)
                print "Got request from %s:%s" % (address, message)
                self.handler._setAddress(self.ss, message, address)
                self.handler.handle(message)
            except (KeyboardInterrupt, SystemExit):
                raise
            except:
                sys.exc_info()[0]

【问题讨论】:

  • “系统中配置的IP”是什么意思? IP是网络栈的一层,而UDP是网络协议?
  • 如果你没有ip地址并且没有连接到任何网络,你期望得到什么消息?
  • @syntonym,希望在没有配置 IP 地址时收到一些广播消息。
  • @JeffCai UDP 定义在 IP 之上。如果您无法获得 IP 消息(如果您没有 IP,则无法获得),您就无法获得 UDP 消息。虽然您应该收到ARPNDP 广播消息。
  • @syntonym,当没有配置IP地址时,主机仍然可以收到DHCP Offer消息,一种IP包。

标签: python udp broadcast


【解决方案1】:

参考pydhcp客户端代码后,我做了如下改动:

import socket
import sys
import select

class Server:

    class Handler:

        def handle(self, message):
            pass

        def __init__(self, serialNo):
            self.serialNo = serialNo

        def _setAddress(self, socket, message, address):
            self.message = message
            self.address = address
            self.socket = socket

        def send(self, message):
            self.socket.sendto(message, self.address)

        def getSerialNo(self):
            return self.serialNo

        def __init__(self, port, handler):
            self.ss = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            self.handler = handler

        try:
            self.ss.bind(("0.0.0.0", int(port)))
        except:
            self.ss.close()
            raise RuntimeError("Create socket error")

        def loop(self):
            while True:
            try:
                print "Listening for broadcast..."
                data_input,data_output,data_except =    select.select([self.ss],[],[], 60)
            if (data_input != []):
               (message, address) = self.ss.recvfrom(2048)
               print "Got request from %s:%s" % (address, message)
               self.handler._setAddress(self.ss, message, address)
               self.handler.handle(message)
            else:
               print "no data within 60 seconds"
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            sys.exc_info()[0]

现在可以接收广播包了,但是在RedHat上就不行了。

【讨论】:

  • 它不使用阻塞套接字,而是使用 select 来监视套接字状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2020-02-28
  • 2013-09-08
  • 1970-01-01
  • 2021-11-05
  • 1970-01-01
相关资源
最近更新 更多