pythonsocketssendto

Python sendto() not executing


I have a program that accepts coordinates over UDP, moves some equipment around, and then replies when the job is done.

I seem to have the same issue as this guy:

Python sendto doesn't seem to send

My code is here:

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

The program behaves as though the sendto call is just passed over; it accepts the packet, executes the print statements, and loops back around (It can execute the loop multiple times but never replies). I'm looking at wireshark and no packets are ever sent outbound. No errors are ever thrown.

Any ideas why this is happening?


Solution

  • From the documentation:

    The string must contain two hexadecimal digits per byte, with ASCII whitespace being ignored.

    So this happens:

    $ 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
    >>> 
    

    Try this:

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

    if that's what you mean.

    Note that your except is catching all the exceptions, not just the ones you're expecting, so you're not seeing the error you're causing. Consider using something like except OSError here instead.

    Also, think about reducing the amount of code in your try sections:

    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
    

    This way you're protecting only the code which you want to.