SoFunction
Updated on 2024-11-12

Beginning Python Socket Programming Tutorial

This is a quick guide and tutorial for learning Python Socket Socket Programming, which is much like C. This is a quick guide and tutorial for learning Python Socket Socket Programming.
The official Python function for sockets is available at/library/
Basically, sockets are the most basic element of any kind of computer network communication. For example, when you type in the address bar of your browser, you open a socket, which then connects to and reads the response page and then displays it. Other chat clients such as gtalk and skype are similar. Any network communication is done through sockets.

Write it at the beginning.

This tutorial assumes that you already have some basic knowledge of Python programming.
Let's get started with socket programming.

Creating a Socket

The first thing to do is to create a Socket, socket socket function can be realized, the code is as follows:

Copy Code The code is as follows.

#Socket client example in python

import socket #for sockets

#create an AF_INET, STREAM socket (TCP)
s = (socket.AF_INET, socket.SOCK_STREAM)

print 'Socket Created'

function creates a Socket and returns a descriptor for the Socket that can be used in other Socket-related functions.
The above code uses the following two properties to create the Socket:
Address Cluster : AF_INET (IPv4)
Type: SOCK_STREAM (using TCP Transmission Control Protocol)

error handling

If the socket function fails, python will throw an exception called which must be handled:

Copy Code The code is as follows.

#handling errors in python socket programs

import socket #for sockets
import sys #for exit

try:
    #create an AF_INET, STREAM socket (TCP)
    s = (socket.AF_INET, socket.SOCK_STREAM)
except , msg:
    print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
    ();

print 'Socket Created'

Okay, assuming you've successfully created the socket, what's the next step? Next we will use this socket to connect to the server.

Caution.

The other counterpart to SOCK_STREAM is SOCK_DGRAM which is used for the UDP communication protocol, which is a non-connected socket, and in this article we will only discuss SOCK_STREAM, or TCP.

Connecting to the server

To connect to the server, you need the server address and port number, which are used here and port 80.

First get the IP address of the remote host

Before we can connect to a remote host, we need to know its IP address, and in Python, getting an IP address is easy:

Copy Code The code is as follows.

import socket #for sockets
import sys #for exit

try:
    #create an AF_INET, STREAM socket (TCP)
    s = (socket.AF_INET, socket.SOCK_STREAM)
except , msg:
    print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
    ();

print 'Socket Created'

host = ''

try:
    remote_ip = ( host )

except :
    #could not resolve
    print 'Hostname could not be resolved. Exiting'
    ()
   
print 'Ip address of ' + host + ' is ' + remote_ip

We already have the IP address, next we need to specify the port we want to connect to.
Code:

Copy Code The code is as follows.

import socket #for sockets
import sys #for exit

try:
    #create an AF_INET, STREAM socket (TCP)
    s = (socket.AF_INET, socket.SOCK_STREAM)
except , msg:
    print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
    ();

print 'Socket Created'

host = ''
port = 80

try:
    remote_ip = ( host )

except :
    #could not resolve
    print 'Hostname could not be resolved. Exiting'
    ()
   
print 'Ip address of ' + host + ' is ' + remote_ip

#Connect to remote server
((remote_ip , port))

print 'Socket Connected to ' + host + ' on ip ' + remote_ip

Now run the program.

Copy Code The code is as follows.

$ python
Socket Created
Ip address of is 61.145.122.155
Socket Connected to on ip 61.145.122.155

This program creates a Socket and connects to it. Try what happens when you use some other port that doesn't exist (e.g. 81). This logic is equivalent to building a port scanner.
Already connected, the next step is to send data to the server.

friendly reminder

The concept of "connection" is only available with SOCK_STREAM/TCP sockets. A connection implies a reliable mechanism for communicating a stream of data, which can be streamed at the same time. Think of it as a pipeline of data that does not interfere with each other. Another important note: packets are sent and received in a sequential manner.
Other sockets such as UDP, ICMP, and ARP do not have the concept of a "connection"; they are connectionless communications, meaning that you can send and receive packets from or to anyone.

Send data

The sendall function is used to simply send data, let's send some data to oschina:

Copy Code The code is as follows.

import socket #for sockets
import sys #for exit

try:
    #create an AF_INET, STREAM socket (TCP)
    s = (socket.AF_INET, socket.SOCK_STREAM)
except , msg:
    print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
    ();

print 'Socket Created'

host = ''
port = 80

try:
    remote_ip = ( host )

except :
    #could not resolve
    print 'Hostname could not be resolved. Exiting'
    ()
   
print 'Ip address of ' + host + ' is ' + remote_ip

#Connect to remote server
((remote_ip , port))

print 'Socket Connected to ' + host + ' on ip ' + remote_ip

#Send some data to remote server
message = "GET / HTTP/1.1\r\n\r\n"

try :
    #Set the whole string
    (message)
except :
    #Send failed
    print 'Send failed'
    ()

print 'Message send successfully'

In the above example, first connect to the target server and then send the string data "GET / HTTP/1.1\r\n\r\n" which is an HTTP protocol command to get the content of the home page of the website.

Next you need to read the data returned from the server.

receive data

The recv function is used to receive data from a socket:

Copy Code The code is as follows.

#Socket client example in python

import socket #for sockets
import sys #for exit

#create an INET, STREAMing socket
try:
    s = (socket.AF_INET, socket.SOCK_STREAM)
except :
    print 'Failed to create socket'
    ()
   
print 'Socket Created'

host = '';
port = 80;

try:
    remote_ip = ( host )

except :
    #could not resolve
    print 'Hostname could not be resolved. Exiting'
    ()

#Connect to remote server
((remote_ip , port))

print 'Socket Connected to ' + host + ' on ip ' + remote_ip

#Send some data to remote server
message = "GET / HTTP/1.1\r\nHost: \r\n\r\n"

try :
    #Set the whole string
    (message)
except :
    #Send failed
    print 'Send failed'
    ()

print 'Message send successfully'

#Now receive data
reply = (4096)

print reply

The following is the result of the execution of the above program:

Copy Code The code is as follows.

$ python
Socket Created
Ip address of is 61.145.122.
Socket Connected to on ip 61.145.122.155
Message send successfully
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Wed, 24 Oct 2012 13:26:46 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Keep-Alive: timeout=20
Location: https:///

It responds with the contents of the URL we requested, simple enough. Now that you've received your data, you can close the socket.

Close socket

The close function is used to close the Socket:

Copy Code The code is as follows.
()

That's it.

Let's review.

In the above example we learned how:
1. Creating Sockets
2. Connecting to remote servers
3. Transmission of data
4. Receiving responses

When you open it in a browser, the process is the same. There are two types, client and server, where the client connects to the server and reads the data, and the server receives the incoming connection and provides the data using a socket. So in this case it's the server and your browser is the client.
Next we start doing a bit of coding on the server side.

server-side programming

Server-side programming consists of the following steps:
1. Open the socket
2. Bind to an address and port
3. Listening for incoming connections
4. Acceptance of connections
5. Reading and writing data
We've already learned how to open a socket, here's how to bind to a specific address and port.

Binding Socket

The bind function is used to bind a socket to a specific address and port, and requires a sockaddr_in structure similar to that required by the connect function.
Sample code:

Copy Code The code is as follows.

import socket
import sys

HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = (socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    ((HOST, PORT))
except , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    ()
   
print 'Socket bind complete'

Once the binding is complete, you need to get the socket to start listening for connections. Obviously, you can't bind two different sockets to the same port.

Connection Listening

After binding the socket we can start listening for connections, we need to put the socket into listen mode. socket's listen function is used to implement listen mode:

Copy Code The code is as follows.

(10)
print 'Socket now listening'

The listen function takes a parameter called backlog, which controls the number of connections that can be kept waiting while the program is busy. Here we pass 10, which means that if there are already 10 connections waiting to be processed, then the 11th connection will be rejected. This becomes clearer when socket_accept is checked.

accept a connection
Sample code:

Copy Code The code is as follows.

import socket
import sys

HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = (socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    ((HOST, PORT))
except , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    ()
   
print 'Socket bind complete'

(10)
print 'Socket now listening'

#wait to accept a connection - blocking call
conn, addr = ()

#display client information
print 'Connected with ' + addr[0] + ':' + str(addr[1])

exports
Running the program will display:

Copy Code The code is as follows.
$ python
Socket created
Socket bind complete
Socket now listening

Now this program starts waiting for a connection to come in on port 8888, please do not close this program, let's test it through the telnet program.
Open a command line window and type:

Copy Code The code is as follows.
$ telnet localhost 8888

It will immediately show
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.


And the server-side window shows that:
Copy Code The code is as follows.
$ python
Socket created
Socket bind complete
Socket now listening
Connected with 127.0.0.1:59954

We can see that the client has successfully connected to the server.
In the above example we receive the connection and close it immediately, there is little practical value in such a program, there is usually a lot of things to be done once the connection is established, so let's give the client something to respond to.
The sendall function sends data to the client over a socket:

Copy Code The code is as follows.

import socket
import sys

HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = (socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    ((HOST, PORT))
except , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    ()
   
print 'Socket bind complete'

(10)
print 'Socket now listening'

#wait to accept a connection - blocking call
conn, addr = ()

print 'Connected with ' + addr[0] + ':' + str(addr[1])

#now keep talking with the client
data = (1024)
(data)

()
()

Continue to run the above code and then open another command line window and enter the following command:

Copy Code The code is as follows.
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
happy
happy
Connection closed by foreign host.

You can see that the client receives the content of the response from the server side.
The above example is still the same, the server side responds and exits immediately. Some real servers like this are always running, accepting connection requests all the time.
This means that the server side should always be running, otherwise it can't be a "service", so the easiest way to keep the server side running is to put the accept method inside a loop.

Servers that are always running

Minor changes to the above code:

Copy Code The code is as follows.

import socket
import sys

HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = (socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    ((HOST, PORT))
except , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    ()
   
print 'Socket bind complete'

(10)
print 'Socket now listening'

#now keep talking with the client
while 1:
    #wait to accept a connection - blocking call
    conn, addr = ()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])
   
    data = (1024)
    reply = 'OK...' + data
    if not data:
        break
   
    (reply)

()
()

It's as simple as adding an extra while 1 statement.
Go ahead and run the server, then open three other command-line windows. Each window uses the telnet command to connect to the server:

Copy Code The code is as follows.
$ telnet localhost 5000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
happy
OK .. happy
Connection closed by foreign host.

The terminal window where the server is located is displayed:
Copy Code The code is as follows.
$ python
Socket created
Socket bind complete
Socket now listening
Connected with 127.0.0.1:60225
Connected with 127.0.0.1:60237
Connected with 127.0.0.1:60239

You see that the server won't quit anymore, well, shut down the server with Ctrl+C and all telnet terminals will show "Connection closed by foreign host."
That's good enough, but it's too inefficient to communicate that way; the server program uses a loop to accept connections and send responses, which is equivalent to handling at most one client request at a time, and we require the server to be able to handle multiple requests at once.

Handling multiple connections

In order to handle multiple connections, we need a separate processing code to run when the main server receives a connection. One way to do this is to use threads, where the server receives the connection and then creates a thread to handle the connection sending and receiving data, and then the main server program returns to receive the new connection.
Here's how we use threads to handle connection requests:

Copy Code The code is as follows.
import socket
import sys
from thread import *

HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = (socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

#Bind socket to local host and port
try:
    ((HOST, PORT))
except , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    ()
   
print 'Socket bind complete'

#Start listening on socket
(10)
print 'Socket now listening'

#Function for handling connections. This will be used to create threads
def clientthread(conn):
    #Sending message to connected client
    ('Welcome to the server. Type something and hit enter\n') #send only takes string
   
    #infinite loop so that function do not terminate and thread do not end.
    while True:
       
        #Receiving from client
        data = (1024)
        reply = 'OK...' + data
        if not data:
            break
   
        (reply)
   
    #came out of loop
    ()

#now keep talking with the client
while 1:
    #wait to accept a connection - blocking call
    conn, addr = ()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])
   
    #start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
    start_new_thread(clientthread ,(conn,))

()

Run the above server-side program, then open three terminal windows as before and execute the telent command:

Copy Code The code is as follows.
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome to the server. Type something and hit enter
hi
OK...hi
asd
OK...asd
cv
OK...cv

The output message of the terminal window where the server side is located is as follows:
Copy Code The code is as follows.
$ python
Socket created
Socket bind complete
Socket now listening
Connected with 127.0.0.1:60730
Connected with 127.0.0.1:60731

The thread takes over the connection and returns the appropriate data to the client.
This is the server-side programming that we are going to cover.

reach a verdict

Up to this point, you've learned the basics of socket programming in Python, and you can reinforce that knowledge by writing some examples of your own.
You may encounter some problems: Bind failed. Error Code : 98 Message Address already in use, you can simply change the server port if you encounter this problem.