The Socket API provides a set of functions to create, configure, and use sockets. This module covers the core functions used in socket programming.
Core Socket Functions
socket() - Create a Socket
Purpose: Creates a new socket
Syntax (Python):
socket.socket(family, type, protocol=0)
Parameters:
- family: Address family (AF_INET, AF_INET6, AF_UNIX)
- type: Socket type (SOCK_STREAM, SOCK_DGRAM)
- protocol: Protocol number (usually 0 for auto-select)
Returns: Socket object/file descriptor
Example:
import socket
# Create TCP socket
tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Create UDP socket
udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
In C:
int socket(int domain, int type, int protocol);
bind() - Bind Socket to Address
Purpose: Associates a socket with a specific IP address and port
Syntax (Python):
socket.bind(address)
Parameters:
- address: Tuple (host, port)
- host: IP address string or '' (all interfaces) or 'localhost'
- port: Port number (integer)
Returns: None (raises exception on error)
Example:
# Bind to all interfaces on port 8080
server.bind(('', 8080))
# Bind to localhost only
server.bind(('127.0.0.1', 8080))
# Bind to specific interface
server.bind(('192.168.1.100', 8080))
Common Errors:
- OSError: [Errno 48] Address already in use - Port in use
- OSError: [Errno 13] Permission denied - Need privileges for port < 1024
In C:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
listen() - Listen for Connections (TCP Server)
Purpose: Makes socket listen for incoming connections (TCP only)
Syntax (Python):
socket.listen(backlog)
Parameters:
- backlog: Maximum number of pending connections
Returns: None (raises exception on error)
Example:
# Allow up to 5 pending connections
server.listen(5)
# Common default value
server.listen(socket.SOMAXCONN) # System maximum
Note: Must call bind() before listen()
In C:
int listen(int sockfd, int backlog);
accept() - Accept Connection (TCP Server)
Purpose: Accepts an incoming connection and returns a new socket for communication
Syntax (Python):
socket.accept()
Parameters: None
Returns: Tuple (socket, address)
- socket: New socket for client communication
- address: Tuple (ip, port) of client
Behavior: Blocks until a connection is available
Example:
# Accept connection
client_socket, client_address = server.accept()
print(f"Connection from {client_address}")
# Use client_socket to communicate with client
Note: The original server socket continues listening for more connections
In C:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
connect() - Connect to Server (TCP Client)
Purpose: Initiates connection to a server (TCP only)
Syntax (Python):
socket.connect(address)
Parameters:
- address: Tuple (host, port) of server
Returns: None (raises exception on error)
Example:
# Connect to server
client.connect(('192.168.1.100', 8080))
# Connect using domain name
client.connect(('example.com', 80))
Common Errors:
- ConnectionRefusedError - Server not listening
- TimeoutError - Connection timed out
- gaierror - Hostname resolution failed
In C:
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
send() - Send Data (TCP)
Purpose: Sends data over a connected TCP socket
Syntax (Python):
socket.send(bytes)
Parameters:
- bytes: Data to send (bytes object)
Returns: Number of bytes sent (may be less than requested)
Example:
message = b"Hello, Server!"
bytes_sent = client.send(message)
print(f"Sent {bytes_sent} bytes")
Important: send() may not send all data at once. Use loop if needed:
def send_all(sock, data):
total_sent = 0
while total_sent < len(data):
sent = sock.send(data[total_sent:])
if sent == 0:
raise RuntimeError("Socket connection broken")
total_sent += sent
In C:
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
recv() - Receive Data (TCP)
Purpose: Receives data from a connected TCP socket
Syntax (Python):
socket.recv(bufsize)
Parameters:
- bufsize: Maximum number of bytes to receive
Returns: Bytes received (empty bytes if connection closed)
Behavior: Blocks until data is available or connection closes
Example:
# Receive up to 1024 bytes
data = client.recv(1024)
if not data:
print("Connection closed")
else:
print(f"Received: {data.decode()}")
Important: recv() may return partial data. You may need multiple calls:
def recv_all(sock, size):
data = b''
while len(data) < size:
chunk = sock.recv(size - len(data))
if not chunk:
break
data += chunk
return data
In C:
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
sendto() - Send Data (UDP)
Purpose: Sends data to a specific address (UDP)
Syntax (Python):
socket.sendto(bytes, address)
Parameters:
- bytes: Data to send
- address: Tuple (host, port) of destination
Returns: Number of bytes sent
Example:
message = b"Hello, Server!"
udp_socket.sendto(message, ('192.168.1.100', 8080))
Note: No connection needed for UDP
In C:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
recvfrom() - Receive Data (UDP)
Purpose: Receives data and sender's address (UDP)
Syntax (Python):
socket.recvfrom(bufsize)
Parameters:
- bufsize: Maximum number of bytes to receive
Returns: Tuple (data, address)
- data: Received bytes
- address: Tuple (ip, port) of sender
Example:
data, addr = udp_socket.recvfrom(1024)
print(f"Received from {addr}: {data.decode()}")
In C:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
close() - Close Socket
Purpose: Closes the socket and releases resources
Syntax (Python):
socket.close()
Example:
client.close()
server.close()
Note: - For TCP: Sends FIN packet to close connection gracefully - Always close sockets when done
In C:
int close(int fd);
TCP Socket Lifecycle
Server Side
# 1. Create socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. Bind to address
server.bind(('localhost', 8080))
# 3. Listen for connections
server.listen(5)
# 4. Accept connections (loop)
while True:
client, addr = server.accept()
# 5. Communicate
data = client.recv(1024)
client.send(b"Response")
# 6. Close client socket
client.close()
# 7. Close server socket
server.close()
Client Side
# 1. Create socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. Connect to server
client.connect(('localhost', 8080))
# 3. Send data
client.send(b"Hello")
# 4. Receive data
response = client.recv(1024)
# 5. Close socket
client.close()
UDP Socket Lifecycle
Server Side
# 1. Create socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. Bind to address
server.bind(('localhost', 8080))
# 3. Receive and send (loop)
while True:
data, addr = server.recvfrom(1024)
server.sendto(b"Response", addr)
# 4. Close socket
server.close()
Client Side
# 1. Create socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. Send data (no connection needed)
client.sendto(b"Hello", ('localhost', 8080))
# 3. Receive response
response, addr = client.recvfrom(1024)
# 4. Close socket
client.close()
Error Handling
Always handle exceptions:
import socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 8080))
except socket.error as e:
print(f"Socket error: {e}")
except Exception as e:
print(f"Error: {e}")
finally:
s.close()
Key Takeaway: These core functions form the foundation of socket programming. Understanding their purpose, parameters, and order of use is essential for building network applications.