Of course! This is a fundamental concept in network programming with Python. Let's break down recv() and recvfrom(), focusing on their differences, use cases, and practical examples.

The Core Concept: Connection-Oriented vs. Connectionless
The key to understanding recv() vs. recvfrom() lies in the type of socket you are using.
recv(): Used with connection-oriented sockets (specifically, TCP sockets). A TCP connection is like a phone call. You first establish a dedicated, reliable channel between two endpoints. Once connected, you don't need to know where the data is coming from because you're already in a conversation with that specific party.recvfrom(): Used with connectionless sockets (specifically, UDP sockets). UDP is like sending a postcard. You just write a message, address it, and send it. You don't have a dedicated connection. Therecvfrom()function must therefore tell you two things: 1) the data that arrived, and 2) the address it came from, so you know who to "reply" to.
socket.recv(bufsize, [flags])
This method is the workhorse for TCP communication.
What it does:
Receives data from the socket. The data is returned as a bytes object. The function will block (wait) until at least one byte of data is available.
Key Parameters:
bufsize(required): An integer specifying the maximum amount of data to be received at once. If the incoming data is larger thanbufsize, the excess data will remain in the operating system's buffer and can be received on a subsequent call torecv().flags(optional): Can be specified as a bitwise OR of values. For most basic use cases, you can omit this. The most common flag issocket.MSG_PEEK, which lets you look at the data in the buffer without removing it.
What it returns:
- A
bytesobject containing the received data. - An empty
bytesobject (b'') if the remote side has closed the connection gracefully. This is the standard way to detect a disconnect in TCP.
socket.recvfrom(bufsize, [flags])
This method is essential for UDP communication.

What it does:
Receives data from the socket, just like recv(). However, it also captures the address of the socket that sent the data.
Key Parameters:
bufsize(required): Same as inrecv(). The maximum number of bytes to receive.flags(optional): Same as inrecv().
What it returns:
A tuple containing two elements:
- A
bytesobject with the received data. - A
tuplerepresenting the sender's address. The format of this address tuple depends on the address family:- For
AF_INET(IPv4):(ip_address, port)(e.g.,('192.168.1.100', 54321)) - For
AF_INET6(IPv6):(ip_address, port, flowinfo, scope_id)
- For
Comparison Table
| Feature | socket.recv() |
socket.recvfrom() |
|---|---|---|
| Socket Type | Connection-Oriented (TCP) | Connectionless (UDP) |
| Use Case | After accept() on a server, or after connect() on a client. |
For servers and clients using datagram sockets. |
| Return Value | bytes object. |
A tuple: (bytes, sender_address). |
| Sender Info | Not needed. The connection is already established. | Crucial. The sender's address is returned. |
| Blocking | Blocks until data is received or connection is closed. | Blocks until a datagram is received. |
Practical Examples
Let's see them in action with a simple TCP echo server and a simple UDP echo server.
Example 1: TCP Echo Server (recv())
The server waits for a connection, then uses recv() to get data from the connected client.

# tcp_server.py
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
print(f"TCP Server listening on {HOST}:{PORT}")
conn, addr = s.accept() # conn is a NEW socket object for the connection
with conn:
print(f"Connected by {addr}")
while True:
data = conn.recv(1024) # Use recv() on the connected socket
if not data:
# If recv() returns an empty bytes object, the client has closed the connection
break
print(f"Received from TCP client: {data.decode('utf-8')}")
conn.sendall(data) # Echo the data back
Example 2: TCP Echo Client (recv())
The client connects to the server and uses recv() to get the response.
# tcp_client.py
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 65432 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
message = b"Hello, TCP Server!"
print(f"Sending to TCP server: {message.decode('utf-8')}")
s.sendall(message)
data = s.recv(1024) # Use recv() to get the response
print(f"Received from TCP server: {data.decode('utf-8')}")
Example 3: UDP Echo Server (recvfrom())
The server uses recvfrom() to get both the data and the client's address in one go.
# udp_server.py
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65433 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.bind((HOST, PORT))
print(f"UDP Server listening on {HOST}:{PORT}")
while True:
# Use recvfrom() to get data and the sender's address
data, addr = s.recvfrom(1024)
print(f"Received from UDP client {addr}: {data.decode('utf-8')}")
# Echo the data back to the same address it came from
s.sendto(data, addr)
Example 4: UDP Echo Client (recvfrom())
The client uses sendto() to send data to a specific address and recvfrom() to get the response.
# udp_client.py
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 65433 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
message = b"Hello, UDP Server!"
# Use sendto() to send data to a specific address
s.sendto(message, (HOST, PORT))
print(f"Sending to UDP server at {HOST}:{PORT}: {message.decode('utf-8')}")
# Use recvfrom() to get the response and the server's address
data, addr = s.recvfrom(1024)
print(f"Received from UDP server {addr}: {data.decode('utf-8')}")
How to Run the Examples
- Save the four files:
tcp_server.py,tcp_client.py,udp_server.py,udp_client.py. - Open two terminal windows.
- In the first terminal, run the TCP server:
python tcp_server.py
You should see:
TCP Server listening on 127.0.0.1:65432 - In the second terminal, run the TCP client:
python tcp_client.py
You will see the client's output, and the server's terminal will show the connection and received data.
- Now, open two new terminals for the UDP example.
- In the third terminal, run the UDP server:
python udp_server.py
You should see:
UDP Server listening on 127.0.0.1:65433 - In the fourth terminal, run the UDP client:
python udp_client.py
You will see the client's output, and the server's terminal will show the received data and the client's address.
