Reputation: 701
As context to my question, I am a computing student getting started with Python for the first time. Before this, I've worked mostly with Java and I am most comfortable with Java conventions and practices right now.
An assignment for socket programming asks that we send strings between a server and client locally on the machine. We are provided sample (Python 2) code that instantiates a server and client. Outside of the context of the assignment, I wanted to create a version of this code that also runs in Python 3, but I was having problems getting the client to work the same in Python 3.
Originally, the server required little changes and I was able to get it working. My code for the server is as follows:
#!/usr/bin/python3
import socket
HOST=''
PORT=5870
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
conn, addr = sock.accept()
print('Connected by ', addr)
conn.sendto("Welcome to the server!", (HOST, PORT))
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
I'm not able to convert the client side to code that runs and functions within Python 3. I've tried digging deeper into the issue, but other online resources are not helpful for me (or at least, at my experience level). My server code is as follows.
#!/usr/bin/python3
import socket
HOST='127.0.0.1'
PORT=5870
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
data = sock.recv(1024)
print('Server sent', data)
sock.sendto("Hello world".encode(), (HOST, PORT))
data = sock.recv(1024)
print("Server sent", data)
sock.sendto("This is the second message".encode(), (HOST, PORT))
data = sock.recv(1024)
print('Server sent ', data)
sock.close()
Originally, this code for both the server and client used sendall()
instead of sendto()
, but I changed it after getting a TypeError
in the client and reading this question. I'm still not exactly sure why this works or why I have to do this (although I would appreciate an explanation).
Now, when I run the client code, I'll get the same TypeError
on the server even when I'm using sendto()
, but I'm not sure how to resolve this problem in Python 3. The stacktrace I receive for the server as follows (I get a broken pipe on the client):
$ python3 mail_server.py
Connected by ('127.0.0.1', 41866)
Traceback (most recent call last):
File "mail_server.py", line 14, in <module>
conn.sendto("Welcome to the server!", (HOST, PORT))
TypeError: a bytes-like object is required, not 'str'
What am I doing wrong and how am I able to get this working in Python 3? Background context as to why this is would be especially helpful as I think part of my problem is that I'm not seeing why this change is necessary to begin with. Thanks!
Upvotes: 4
Views: 13458
Reputation: 781300
Don't use sendto()
on a stream socket. Once a socket is connected (and with stream sockets you can't do any data transfer until after connecting), you can't specify the destination, it's always sent to the remote address/port to which it's connected.
So use send()
or sendall()
:
socket.sendall("Hello world".encode());
Upvotes: 3