【问题标题】:Python sendto() not executingPython sendto()未执行
【发布时间】:2018-10-25 00:43:30
【问题描述】:

我有一个程序通过 UDP 接受坐标,移动一些设备,然后在工作完成后回复。

我好像和这个人有同样的问题:

Python sendto doesn't seem to send

我的代码在这里:

import socket
import struct
import traceback
def main():


    sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    sock.bind(('',15000))
    reply_sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)


    while True:
        try:
            data,addr = sock.recvfrom(1024)
            if data is not None:
                try:
                    coords = struct.unpack('>dd',data)

                    #Stuff happens here 

                    print(f'moved probe to {coords}')

                    reply_sock.sendto(bytearray.fromhex('B'),('10.0.0.32',15001))
                except:
                    traceback.print_exc()
                    try:
                        reply_sock.sendto(bytearray.fromhex('D'),('10.0.0.32',15001))
                    except:
                        traceback.print_exc()
                    break
        except:
            pass

程序的行为就像 sendto 调用刚刚被传递一样;它接受数据包,执行打印语句,然后循环回来(它可以多次执行循环但从不回复)。我正在查看wireshark,并且没有数据包被发送出站。不会抛出任何错误。

任何想法为什么会发生这种情况?

【问题讨论】:

  • 您没有为外部尝试打印任何回溯,因此您可能隐藏了问题

标签: python sockets sendto


【解决方案1】:

来自the documentation

字符串每个字节必须包含两个十六进制数字,使用 ASCII 空白被忽略。

所以这发生了:

$ python3
Python 3.6.6 (default, Sep 12 2018, 18:26:19) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> bytearray.fromhex('B')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: non-hexadecimal number found in fromhex() arg at position 1
>>> 

试试这个:

reply_sock.sendto(bytearray.fromhex('0B'),('10.0.0.32',15001))

如果这就是你的意思。

请注意,您的 except 正在捕获所有异常,而不仅仅是您所期望的异常,因此您看不到您导致的错误。考虑在这里改用except OSError 之类的东西。

另外,考虑减少 try 部分中的代码量:

coords = struct.unpack('>dd',data)

#Stuff happens here 

print(f'moved probe to {coords}')

bytes_to_send = bytearray.fromhex('0B')
try:
    reply_sock.sendto(bytes_to_send,('10.0.0.32',15001))
except IOError as e1:
    print(e1)
    traceback.print_exc()

    bytes_to_send = bytearray.fromhex('0D')
    try:
        reply_sock.sendto(bytes_to_send,('10.0.0.32',15001))
    except IOError as e2:
        print(e2)
        traceback.print_exc()
        break

这样你就只保护你想要的代码。

【讨论】:

  • 非常感谢,这个额外的数字起到了作用。但我对你对我的 except 声明的解释感到困惑。如果 except 捕获所有错误,为什么它没有捕获问题?
  • 查看代码,您说您看到的是print(),所以它就到了那里。然后我希望第一次调用bytearray.fromhex 会让你进入第一个except 部分,所以你会到达traceback.print_exc(),然后下一个try 部分会遇到bytearray.fromhex 的另一个错误,所以你会进入下一个except 部分并到达另一个traceback.print_exc()。这和你看到的相符吗?
  • 我建议的替代方案会导致bytearray.fromhex 中的ValueError 没有被困住,因此您之前会注意到它,而不是隐藏它,并且您假设sendto 导致了问题。
  • 所以我猜发生的事情是,如果您注意到发生了错误,您并没有意识到这是由bytearray.fromhex 引起的ValueError,而不是由OSError 引起的通过sendto。这就是为什么在try 部分中尽可能少地输入和/或非常具体地说明您正在捕获的内容通常会有所帮助。
  • 我查看了异常文档;对我来说没有意义的是 traceback.print_exc() 没有打印任何东西。这是我困惑的根源。为什么异常最终没有被打印出来?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多