SoFunction
Updated on 2024-11-10

A hands-on guide to basic socket programming in Python

In network communication socket is almost ubiquitous, it can be seen as the application layer and the TCP/IP protocol cluster communication of the intermediate software abstraction layer, is the two applications to communicate with each other interface, and the complexity of the TCP/IP protocol details are hidden in the interface after the Python provides a socket module, you can very easily carry out socket programming.

Create a server socket
Creating a new socket using the socket method usually takes two arguments, the first being the address family and the second being the socket type.

#create an INET, STREAMing socket
s = (socket.AF_INET, socket.SOCK_STREAM)

The above creates a socket whose address family is IP and whose transport protocol is TCP.

After the server creates a socket, it needs to bind to an IP address and port to provide services, which requires the bind method.

# bind the socket to all available interfaces on port 8888
(('', 8888))

Use the listen method to set the socket to the listening state. listen is followed by a parameter indicating the maximum number of requests that can be received in the queue.

#become a server socket
(5)

Now that we have created a server socket, we write an infinite loop body that receives connections from the client, utilizing the accept method, which returns a new socket indicating the connection to the remote end, and an address pair indicating the IP address and port number of the remote connection.

# enter the main loop of the web server
while 1:
  #accept connections from outside, return a pair (conn, addr)
  (clientsocket, address) = ()
  #now do something with the clientsocket
  #in this case, we'll pretend this is a threaded server
  ct = client_thread(clientsocket)
  ()

Typically, the server socket in the loop body does not send or receive any data, but simply receives connections from the remote end, hands the new connections off to other threads to process, and then proceeds to listen for more other connections that would otherwise not have been accepted while a connection was being processed.

Next, we create a new thread to process the connection. First, we use the recv method to accept data from the socket, followed by a parameter indicating the maximum size of data that can be accepted at one time. Then we reply to the socket using the sendall method, which keeps sending data until all the data has been sent or an exception occurs. Finally, you need to remember to close the socket, because each socket represents a file descriptor in the system, if you do not close it in time, it may exceed the maximum number of file descriptors in the system, resulting in the inability to create a new socket.

def handle_request(sock, addr):
  print "Accept new connection from {addr}".format(addr = addr)
  request_data = client_connection.recv(1024)
  print request_data.decode()
  http_response = "Hello, world!"
  # send response data to the socket
  (http_response)
  ()

To summarize server socket consists of the following main steps:

  • Create a new server socket;
  • Binds the socket to an address and port;
  • Listen for connections coming in remotely;
  • Accepts the connection and distributes it to other threads.

The following is the complete server socket sample code:

import socket
import threading

SERVER_ADDRESS = (HOST, PORT) = '', 8888
REQUEST_QUEUE_SIZE = 1024

def handle_request(sock, addr):
  print "Accept new connection from {addr}".format(addr = addr)
  request_data = client_connection.recv(1024)
  print request_data.decode()
  http_response = "Hello, world!"
  # send response data to the socket
  (http_response)
  ()

def serve_forever():
  server_socket = (socket.AF_INET, socket.SOCK_STREAM)
  # reuse socket immediately
  server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  server_socket.bind(SERVER_ADDRESS)
  server_socket.listen(REQUEST_QUEUE_SIZE)
  print 'Serving HTTP on port {port} ...'.format(port = PORT)

  while True:
    try:
      client_connection, client_address = server_socket.accept()
    except IOError as e:
      code, msg = 
      # restart 'accept' if it was interrupted
      if code == :
        continue
      else:
        raise
    # create a thread to handle this request
    t = (target=handle_request, args=(sock, addr))
    ()

if __name__ == '__main__':
  serve_forever()

Create a client socket
The client-side socket is a bit simpler and consists of the following steps:

  • Create a socket;
  • Connect to the server;
  • Sends data to the server;
  • Receive data returned from the server;
  • Close the socket.
import socket

HOST = 'localhost' # the remote host
PORT = 8888 # port used by server

client_socket = (socket.AF_INET, socket.SOCK_STREAM)
# connect to server
client_socket.connect((HOST, PORT))
# send something to the server
client_socket.sendall("Hello, world")
data = client_socket.recv(1024)
client_socket.close()
print 'Received', repr(data)

PS: socket module use derivation

sk = (socket.AF_INET,socket.SOCK_STREAM,0)

Parameter 1: Address Cluster

socket.AF_INET IPv4 (default)
socket.AF_INET6 IPv6

socket.AF_UNIX can only be used for inter-process communication on a single Unix system.

Parameter II: Type

socket.SOCK_STREAM streaming socket , for TCP (default)
socket.SOCK_DGRAM datagram socket , for UDP

socket.SOCK_RAW raw socket, ordinary sockets can not handle ICMP, IGMP and other network messages, while SOCK_RAW can; secondly, SOCK_RAW can also deal with special IPv4 messages; in addition, the use of raw sockets, can be constructed by the user IP header through the IP_HDRINCL socket option.
socket.SOCK_RDM is a form of UDP that is reliable in the sense that delivery of datagrams is guaranteed but not in order.SOCK_RAM is used to provide low-level access to the original protocol and is used when it is necessary to perform some special operation, such as sending ICMP messages.SOCK_RAM is usually restricted to programs run by advanced users or administrators.
socket.SOCK_SEQPACKET Reliable Sequential Packet Service

Parameter III: Protocol

0 (default) Protocol associated with a specific address family, if 0, the system will automatically select an appropriate protocol based on the address format and socket class.

(address)

(address) Binds the socket to an address. address The format of the address depends on the address family. Under AF_INET, the address is represented as a tuple (host,port).

(backlog)

Starts listening for incoming connections. backlog specifies the maximum number of connections that can be hung up before a connection is rejected.

A backlog equal to 5 means that the kernel has received a connection request, but the server has not yet called accept to process the maximum number of connections is 5.
This value cannot be infinitely large because the connection queue has to be maintained in the kernel

(bool)

If or not blocking (default True), if set False, then once there is no data when accept and recv, then report an error.

()

Accepts the connection and returns (conn,address), where conn is a new socket object that can be used to receive and send data. address is the address of the connecting client.

Receiving connections from TCP clients (blocking) Waiting for connections to arrive

(address)

Connects to the socket at address. Normally, address is in the form of a tuple (hostname,port) and returns an error if the connection goes wrong.

sk.connect_ex(address)

Same as above, except that there will be a return value, 0 when the connection succeeds, and a code when the connection fails, e.g., 10061.

()

Close Sockets

(bufsize[,flag])

Accepts data from the socket. The data is returned as a string, and bufsize specifies the maximum number that can be received. flag provides additional information about the message, which can usually be ignored.

(bufsize[.flag])

Similar to recv(), but the return value is (data,address). Where data is the string containing the received data and address is the address of the socket to which the data was sent.

(string[,flag])

Sends the data in string to the connected socket. The return value is the number of bytes to send, which may be less than the byte size of string.

(string[,flag])

Sends the data in string to the connected socket, but tries to send all the data before returning. Success returns None, failure throws an exception.

(string[,flag],address)

Sends data to the socket. address is a tuple of the form (ipaddr, port) specifying the remote address. The return value is the number of bytes sent. This function is mainly used for the UDP protocol.

(timeout)

Sets the timeout period for socket operations. timeout is a floating point number in seconds. A value of None means that there is no timeout period. Generally, the timeout period should be set when the socket is first created, as they may be used for connected operations (e.g., a client connection waits up to 5s).

()
This method can only be used on the client side to view information on the server side
Returns the remote address of the connection socket. The return value is usually a tuple (ipaddr,port).

()
This method can only be used on the server side to view the server's own information.
Returns the socket's own address. Usually a tuple (ipaddr,port)

()

The file descriptor for the socket