Python Advanced - Networking with Sockets
Introduction to networking with sockets in Python
Networking with sockets is a fundamental aspect of building networked applications. Sockets provide a way to connect two nodes on a network to communicate with each other. This tutorial introduces the basics of networking with sockets in Python, including creating server and client applications.
Key Points:
- Sockets provide a way to connect two nodes on a network for communication.
- Python's
socket
module provides a low-level interface for working with sockets. - You can create both server and client applications using sockets.
Creating a Socket
To create a socket in Python, you use the socket
module and create a socket
object. You need to specify the address family (e.g., AF_INET
for IPv4) and the socket type (e.g., SOCK_STREAM
for TCP):
import socket
# Create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Creating a Server
A server socket binds to a specific IP address and port, listens for incoming connections, and accepts them:
import socket
def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("localhost", 12345))
server_socket.listen(5)
print("Server listening on port 12345")
while True:
client_socket, addr = server_socket.accept()
print(f"Connection from {addr}")
client_socket.send(b"Hello from server!")
client_socket.close()
if __name__ == "__main__":
start_server()
In this example, the server socket binds to localhost
on port 12345
, listens for incoming connections, and sends a greeting message to the client.
Creating a Client
A client socket connects to a server using the server's IP address and port. After establishing the connection, the client can send and receive data:
import socket
def start_client():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("localhost", 12345))
message = client_socket.recv(1024)
print(f"Received from server: {message.decode()}")
client_socket.close()
if __name__ == "__main__":
start_client()
In this example, the client socket connects to the server on localhost
port 12345
and receives a greeting message from the server.
Handling Multiple Clients
To handle multiple clients, you can use threading or multiprocessing. Here's an example using threading:
import socket
import threading
def handle_client(client_socket):
message = client_socket.recv(1024)
print(f"Received: {message.decode()}")
client_socket.send(b"Hello from server!")
client_socket.close()
def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("localhost", 12345))
server_socket.listen(5)
print("Server listening on port 12345")
while True:
client_socket, addr = server_socket.accept()
print(f"Connection from {addr}")
client_handler = threading.Thread(target=handle_client, args=(client_socket,))
client_handler.start()
if __name__ == "__main__":
start_server()
In this example, each client connection is handled in a separate thread, allowing the server to handle multiple clients concurrently.
Sending and Receiving Data
You can send and receive data using the send()
and recv()
methods. It's important to handle data in chunks if the size is unknown or large:
# Example of sending and receiving data
# Server
import socket
def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("localhost", 12345))
server_socket.listen(5)
print("Server listening on port 12345")
while True:
client_socket, addr = server_socket.accept()
print(f"Connection from {addr}")
data = b""
while True:
chunk = client_socket.recv(1024)
if not chunk:
break
data += chunk
print(f"Received: {data.decode()}")
client_socket.send(b"Data received")
client_socket.close()
if __name__ == "__main__":
start_server()
# Client
import socket
def start_client():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("localhost", 12345))
client_socket.sendall(b"Hello from client!" * 100)
response = client_socket.recv(1024)
print(f"Received from server: {response.decode()}")
client_socket.close()
if __name__ == "__main__":
start_client()
In this example, the server receives data in chunks and the client sends a message repeatedly to demonstrate handling larger data sizes.
Summary
In this tutorial, you learned about networking with sockets in Python. Sockets provide a low-level interface for network communication, allowing you to create server and client applications. You explored creating and binding sockets, handling multiple clients with threading, and sending and receiving data. Understanding socket programming is essential for building networked applications and services in Python.