Python 3 socket programming: using sendall vs. sendto
networking, python, python-3.x, sockets
Solution
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());
Problem
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. Background 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. Changing server and client 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() ``` The actual problem 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!