Socket Programming
Network protocols
TCP/IP is a suite of protocols used by devices to communicate over the Internet and most local networks. TCP is more reliable, has extensive error checking, and requires more resources. It is used by services such as HTTP, SMTP, or FTP. UDP is much less reliable, has limited error checking, and requires less resources. It is used by services such as VoIP.
The socket.SOCK_STREAM
is used to create a socket for TCP
The socket.SOCK_DGRAM
is used to create a socket for UDP.
Address families
When we create a socket, we have to specify its address family. Then we can only use addresses of that type with the socket.
AF_UNIX, AF_LOCAL - Local communication
AF_INET - IPv4 Internet protocols
AF_INET6 - IPv6 Internet protocols
AF_IPX - IPX - Novell protocols
AF_BLUETOOTH - Wireless bluetooth protocols
AF_PACKET - Low level packet interface
For the AF_INET
address family, a pair (host, port) is specified. The host
is a string representing either a hostname in Internet domain notation like google.com
or an IPv4 address like 93.184.216.34
, and port is an integer.
Get IP address
With gethostbyname
, we get the IP address of the host.
UDP socket example
UDP is a communication protocol that transmits independent packets over the network with no guarantee of arrival and no guarantee of the order of delivery. One service that used UDP is the Quote of the Day (QOTD).
qotd_client.py
Explaining
UDP sockets use recvfrom
to receive data. Its paremeter is the buffer size. The return value is a pair (data, address) where data is a byte string representing the data received and address is the address of the socket sending the data.
We send data with the sendto
method.
We provide the address and the port.
We send an empty message; the QOTD service works by sending arbitrary data to the socket; it simply responds with a quote. To communicate over TCP/UDP, we use binary strings.
A datagram socket for IPv4 is created.
We import the socket
module.
The example creates a client program that connects to a QOTD service.
TCP socket example
The are servers that provide current time. A client simply connects to the server with no commands, and the server responds with a current time.
The example determines the current time by connecting to a time server's TCP socket.
A TCP socket for IPv4 is created.
This is the host name and the port number of a working time server.
We connect to the remote socket with connect
.
The sendall
method sends data to the socket. The socket must be connected to a remote socket. It continues to send data from bytes until either all data has been sent or an error occurs.
We print the received data. The recv
method receives up to buffersize bytes from the socket. When no data is available, it blocks until at least one byte is available or until the remote end is closed. When the remote end is closed and all data is read, it returns an empty byte string.
Socket HEAD request
A HEAD request is a GET request without a message body. The header of a request/response contains metadata, such as HTTP protocol version or content type.
In the example, we send a HEAD request to webcode.me
.
A head request is issued with the HEAD
command followed by the resource URL and HTTP protocol version. Note that the \r
are mandatory part of the communication process. The details are described in RFC 7231 document.
Socket GET request
The HTTP GET method requests a representation of the specified resource. Requests using GET should only retrieve data.
The example reads the home page of the webcode.me
using a GET request.
For the HTTP 1.1 protocol, the connections may be persistent by default. This is why we send the Connection: close
header.
We use a while loop to process the received data. If no error occurs, recv
returns the bytes received. If the connection has been gracefully closed, the return value is an empty byte string. The recv
is a blocking method that blocks until it is done, or a timeout is reached or another exception occurs.
Echo client server example
An echo server sends the message from the client back. It is a classic example used for testing and learning.
The echo server sends the client message back to the client.
The server runs on localhost on port 8001.
The bind
method establishes the communication endpoint. It binds the socket to the specified address. The socket must not already be bound. (The format of address depends on the address family.)
The listen
method enables a server to accept connections. The server can now listen for connections on a socket. The listen
has a backlog
parameter. It specifies the number of unaccepted connections that the system will allow before refusing new connections. The parameter is optional since Python 3.5. If not specified, a default backlog value is chosen.
With accept
, the server accepts a connection. It blocks and waits for an incoming connection. The socket must be bound to an address and listening for connections. The return value is a pair (con, addr) where con is a new socket object usable to send and receive data on the connection, and addr is the address bound to the socket on the other end of the connection.
Note that the accept
creates a new socket for communication with a client, which is a different socket from the listening socket.
The client sends a message to the echo server.
Asynchronous server example
In order to improve the performance of a server, we can use the asyncio
module.
We can now test the performance of the blocking and non-blocking servers.
For instance, we can test the performance with the Apache benchmarking tool. In our case, the command sends 1000 requests, 50 at a time.
In this tutorial, we have showed how to create simple networking programs with sockets in Python.
Last updated