Hat
Hat

Reputation: 1731

python socket.sendto

I'm new to python(3.3) networking programming, so to start off I was trying to write a basic traceroute program. One of the lines of code is:

send_socket.sendto(512, '', (dest_name, port))

I am getting an error for this line in the console stating "TypeError: 'int' does not support the buffer interface". I tried with a sting and I got the same error with 'str' instead of 'int'. I also looked at the documentation, and tried a couple other formulations to no avail.

Does anyone have experience with this?

import socket

def main(dest_name):
    dest_addr = socket.gethostbyname(dest_name)
    port = 33434
    icmp = socket.getprotobyname('icmp')
    udp = socket.getprotobyname('udp')
    ttl = 1
    while True:
        recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
        send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
        send_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
        recv_socket.bind(('', port))
        send_socket.sendto('', (dest_name, port))
        curr_addr = None
        curr_name = None
        try:
            _, curr_addr = recv_socket.recvfrom(512)
            curr_addr = curr_addr[0]
            try:
                curr_name = socket.gethostbyaddr(curr_addr)[0]
            except socket.error:
                curr_name = curr_addr
        except socket.error:
            pass
        finally:
            send_socket.close()
            recv_socket.close()

        if curr_addr is not None:
            curr_host = '%s (%s)' % (curr_name, curr_addr)
        else:
            curr_host = '*'
        print "%d\t%s" % (ttl, curr_host)

        ttl += 1
        if curr_addr == dest_addr or ttl > max_hops:
            break

if __name__ == '__main__':
    main('www.google.com')

Upvotes: 2

Views: 48890

Answers (2)

Sudip Das
Sudip Das

Reputation: 1208

Encode the string to bytes because sendto does not accept string objects

MESSAGE="Hello !!"
soc.sendto(MESSAGE.encode('utf-8'), (dest_name, port))

received_bytes, peer = con.recvfrom()
print("Received %s from %s:%u" % (received_bytes.decode('utf8'), peer[0], peer[1])

Also worth noting that you can send arbitrary data with these network functions and it does not need to be encoded text. e.g. soc.sendto(b'\xff', (host, port)) is perfectly valid to send a single FF byte in a UDP packet and will not decode as UTF8 using the above code.

Upvotes: 4

perreal
perreal

Reputation: 98108

Convert the message to string:

sock.sendto(bytes(512), (dest_name, port))

Upvotes: 3

Related Questions