Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple 'chat' UDP client and server using Python, can't use `str` as `send()` payload

Tags:

python

udp

Iam trying to do a simple 'chat' using UDP in python. I have done both client and server code that is,

client

import socket
fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM )
udp_ip = '127.0.0.1'
udp_port = 8014
while(True):
    message = input("Client :")
    fd.sendto(message, (udp_ip, udp_port))
    reply = fd.recvfrom(1000)
    print("Server:%s"%(reply))

server

import socket
udp_ip = '127.0.0.1'
udp_port = 8014
fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
fd.bind((udp_ip,udp_port))
while True:
    r = fd.recvfrom(1000)
    print("client : %s"%(r[0]))
    reply = input('server : ')
    client_address = r[1]
    fd.sendto(reply, client_address)  

In the client side iam getting

python client.py 
Client :'haii'

In the server side iam getting,

 python server.py 
 client : 'haii'
 server : 'hai there'
 Traceback (most recent call last):
 File "server.py", line 12, in <module>
 fd.sendto(reply, client_address)
 Type Error: a bytes-like object is required, not 'str'  

How to solve this problem? Is anything wrong there?

~

like image 214
Nitheesh MN Avatar asked Sep 05 '26 08:09

Nitheesh MN


1 Answers

How to solve this problem? Is anything wrong there?

well:

fd.sendto(reply, client_address)
Type Error: a bytes-like object is required, not 'str'

As the error says, you can't directly send a string (Python3 strings are a bit more than just a container of bytes); you must convert it to a bytearray first:

 fd.sendto(bytearray(reply,"utf-8"), client_address)

Notice that you need to specify the encoding; that makes a lot of sense, if you think about how differently characters that aren't usual in English are represented on a byte level. Upside of this conversion is that you can, with unicode, send pretty much anything that is text in any language:

fd.sendto(bytearray("सुंदर भाषा","utf-8"), client_address)

On the other end, you will receive a byte thing, too, and that must be converted to a string first; again, the encoding makes a difference, and you must use the same encoding as to send:

r = fd.recvfrom(1000)
received_msg = str(r, "utf-8")

Your print("%s" % r ) implicitly calls str with default encoding, but that is very likely not a good idea in a network thing. Using utf-8 is pretty much a very good approach to encode strings as bytes.

To give a minimal amount of background: A string should really behave like a string – i.e., a piece of text composed of letters/glyphs/symbols, a representation of text, not some piece of binary memory. Hence, when sending a piece of memory over to someone else, you need to make sure that your text is understood based on a common representation, in this case, UTF8, on both ends.

like image 129
Marcus Müller Avatar answered Sep 06 '26 22:09

Marcus Müller



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!