This is a guide and tutorial for quickly learning Python socket programming. Python's Socket programming is much like the C language.
Python official about Socket function See http://docs.python.org/library/socket.html
Basically, the Socket is the most basic content in any kind of computer network communication. For example, when you enter www.bitsCN.com in the browser address bar, you open a socket and then connect to www.bitsCN.com and read the response page and then display it. Other chat clients, such as Gtalk and Skype, are similar. Any network communication is done through a Socket.
Write at the beginning
This tutorial assumes that you already have some basic knowledge of Python programming.
Let's start with Socket programming.
Create Socket
The first thing to do is to create a socket,socket Socket function can be implemented, the code is as follows:
The code is as follows:
#Socket Client example in Python
Import Socket #for sockets
#create an af_inet, STREAM socket (TCP)
s = socket.socket (socket.af_inet, socket. SOCK_STREAM)
print ' Socket Created '
The function Socket.socket creates a socket and returns a socket descriptor that can be used for other socket-related functions.
The code above uses the following two properties to create a Socket:
Address cluster: af_inet (IPV4)
Type: Sock_stream (using TCP Transmission Control Protocol)
Error handling
If the socket function fails, Python throws an exception named Socket.error, which must be handled:
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.socket (socket.af_inet, socket. SOCK_STREAM)
Except Socket.error, msg:
print ' Failed to create socket. Error code: ' + str (msg[0]) + ', error message: ' + msg[1]
Sys.exit ();
print ' Socket Created '
Well, assuming you've successfully created the Socket, what's the next step? Next we will use this Socket to connect to the server.
Attention:
Other types corresponding to Sock_stream are SOCK_DGRAM for UDP communication protocol, UDP communication is a non-connected Socket, in this article we only discuss Sock_stream, or TCP.
Connect to Server
Connecting to the server requires a server address and port number, which is used for www.bitsCN.com and 80 ports.
First get the IP address of the remote host
Before connecting to a remote host, we need to know its IP address, in Python, it is very simple to obtain an IP address:
The code is as follows:
Import Socket #for sockets
Import SYS #for exit
Try
#create an af_inet, STREAM socket (TCP)
s = socket.socket (socket.af_inet, socket. SOCK_STREAM)
Except Socket.error, msg:
print ' Failed to create socket. Error code: ' + str (msg[0]) + ', error message: ' + msg[1]
Sys.exit ();
print ' Socket Created '
Host = ' www.bitsCN.com '
Try
REMOTE_IP = Socket.gethostbyname (host)
Except Socket.gaierror:
#could not resolve
print ' Hostname could not being resolved. Exiting '
Sys.exit ()
print ' Ip address of ' + host + ' is ' + remote_ip
We already have an IP address, and then we need to specify the port to connect to.
Code:
The code is as follows:
Import Socket #for sockets
Import SYS #for exit
Try
#create an af_inet, STREAM socket (TCP)
s = socket.socket (socket.af_inet, socket. SOCK_STREAM)
Except Socket.error, msg:
print ' Failed to create socket. Error code: ' + str (msg[0]) + ', error message: ' + msg[1]
Sys.exit ();
print ' Socket Created '
Host = ' www.bitsCN.com '
Port = 80
Try
REMOTE_IP = Socket.gethostbyname (host)
Except Socket.gaierror:
#could not resolve
print ' Hostname could not being resolved. Exiting '
Sys.exit ()
print ' Ip address of ' + host + ' is ' + remote_ip
#Connect to remote server
S.connect ((remote_ip, Port))
print ' Socket Connected to ' + Host + ' on IP ' + remote_ip
Run the program now
The code is as follows:
$ python client.py
Socket Created
Ip address of Www.bitsCN.com is 61.145.122.155
Socket Connected to www.bitsCN.com on IP 61.145.122.155
This program creates a Socket and connects and tries to use some other non-existent ports (such as 81). This logic is equivalent to building a port scanner.
is already connected, the next step is to send the data to the server.
Friendly Tips
The concept of "connection" is only available with SOCK_STREAM/TCP sockets. Connectivity means a reliable data flow mechanism that can have multiple data streams at the same time. You can imagine a pipeline where data doesn't interfere with each other. Another important tip is that the packets are sent and received sequentially.
Some other sockets, such as UDP, ICMP, and ARP, do not have a "connection" concept, they are non-connected communications, which means that you can send and receive packets from anyone or to anyone.
Send data
The Sendall function is used to simply send data, and we send some data to Oschina:
The code is as follows:
Import Socket #for sockets
Import SYS #for exit
Try
#create an af_inet, STREAM socket (TCP)
s = socket.socket (socket.af_inet, socket. SOCK_STREAM)
Except Socket.error, msg:
print ' Failed to create socket. Error code: ' + str (msg[0]) + ', error message: ' + msg[1]
Sys.exit ();
print ' Socket Created '
Host = ' www.bitsCN.com '
Port = 80
Try
REMOTE_IP = Socket.gethostbyname (host)
Except Socket.gaierror:
#could not resolve
print ' Hostname could not being resolved. Exiting '
Sys.exit ()
print ' Ip address of ' + host + ' is ' + remote_ip
#Connect to remote server
S.connect ((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
S.sendall (Message)
Except Socket.error:
#Send failed
print ' Send failed '
Sys.exit ()
print ' Message send successfully '
In the example above, 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 homepage of the website.
Next, you need to read the data returned by the server.
Receive data
The RECV function is used to receive data from the socket:
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.socket (socket.af_inet, socket. SOCK_STREAM)
Except Socket.error:
print ' Failed to create socket '
Sys.exit ()
print ' Socket Created '
Host = ' bitscn.com ';
Port = 80;
Try
REMOTE_IP = Socket.gethostbyname (host)
Except Socket.gaierror:
#could not resolve
print ' Hostname could not being resolved. Exiting '
Sys.exit ()
#Connect to remote server
S.connect ((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:bitscn.com\r\n\r\n"
Try:
#Set the whole string
S.sendall (Message)
Except Socket.error:
#Send failed
print ' Send failed '
Sys.exit ()
print ' Message send successfully '
#Now Receive data
Reply = S.recv (4096)
Print reply
The following are the results of the above program execution:
The code is as follows:
$ python client.py
Socket Created
Ip address of bitscn.com is 61.145.122.
Socket Connected to bitscn.com on IP 61.145.122.155
Message Send successfully
http/1.1 301 Moved Permanently
Server:nginx
date:wed, Oct 13:26:46 GMT
Content-type:text/html
content-length:178
Connection:keep-alive
Keep-alive:timeout=20
location:http://www.bitscn.com/
Bitscn.com responded to the content of the URL we requested, very simply. After the data has been received, the Socket can be closed.
Close socket
The close function is used to close the Socket:
The code is as follows:
S.close ()
That's it.
Let's take a look back
In the example above, we learned how to:
1. Create a Socket
2. Connect to a remote server
3. Send data
4. Receiving a response
When you open www.bitsCN.com with a browser, the process is the same. Consists of two types, the client and the server, the client connects to the server and reads the data, and the server uses the Socket to receive the incoming connection and provide the data. So here www.bitsCN.com is the server side, and your browser is the client.
Next we begin to do some coding on the server side.
Server-side programming
Server-side programming consists mainly of the following steps:
1. Open the socket
2. Bind to an address and port
3. Listening for incoming connections
4. Accept the connection
5. Read and write Data
We have learned how to open the Socket, and the following is bound to the specified address and port.
Bind Socket
The BIND function is used to bind a Socket to a specific address and port, which requires a sockaddr_in structure similar to the one required by the Connect function.
Example 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.socket (socket.af_inet, socket. SOCK_STREAM)
print ' Socket created '
Try
S.bind ((HOST, PORT))
Except Socket.error, msg:
print ' Bind failed. Error Code: ' + str (msg[0]) + ' Message ' + msg[1]
Sys.exit ()
print ' Socket bind complete '
Once the bindings are complete, you need to let the Socket start listening for connections. Obviously, you can't bind two different sockets to the same port.
Connection Listening
After you bind the socket, you can start listening to the connection and we need to turn the socket into a listening mode. The listen function of the socket is used to implement the listening mode:
The code is as follows:
S.listen (10)
print ' Socket now listening '
The parameters required by the Listen function become the backlog, which is used to control the number of connections that can remain in the waiting state while busy. Here we pass 10, meaning that if there are already 10 connections waiting to be processed, the 11th connection will be rejected. This will be clearer when the socket_accept is checked.
Accept Connection
Example 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.socket (socket.af_inet, socket. SOCK_STREAM)
print ' Socket created '
Try
S.bind ((HOST, PORT))
Except Socket.error, msg:
print ' Bind failed. Error Code: ' + str (msg[0]) + ' Message ' + msg[1]
Sys.exit ()
print ' Socket bind complete '
S.listen (10)
print ' Socket now listening '
#wait to accept a connection-blocking call
conn, addr = S.accept ()
#display Client Information
print ' Connected with ' + addr[0] + ': ' + str (addr[1])
Output
Running the program will show:
The code is as follows:
$ python server.py
Socket created
Socket bind complete
Socket now listening
Now this program begins to wait for the connection to enter, the port is 8888, please do not close this program, we come through the Telnet program to test.
Open a command-line window and enter:
The code is as follows:
$ telnet localhost 8888
It'll 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:
The code is as follows:
$ python server.py
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.
The above example we receive the connection and immediately shut down, such a program is no real value, the connection after the establishment of a lot of things need to deal with, so let's give the client to respond to it.
The Sendall function can send data to the client via the Socket:
The code is as follows:
Import socket
Import Sys
HOST = ' # symbolic name meaning all available interfaces
Port = 8888 # arbitrary non-privileged port
s = socket.socket (socket.af_inet, socket. SOCK_STREAM)
print ' Socket created '
Try
S.bind ((HOST, PORT))
Except Socket.error, msg:
print ' Bind failed. Error Code: ' + str (msg[0]) + ' Message ' + msg[1]
Sys.exit ()
print ' Socket bind complete '
S.listen (10)
print ' Socket now listening '
#wait to accept a connection-blocking call
conn, addr = S.accept ()
print ' Connected with ' + addr[0] + ': ' + str (addr[1])
#now keep talking with the client
data = CONN.RECV (1024)
Conn.sendall (data)
Conn.close ()
S.close ()
Continue running the above code and open another command line window to enter the following command:
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 response from the server side.
The example above is still the same, and the server responds with an immediate exit. While some real servers like www.bitsCN.com are always running, accept connection requests at all times.
That is, the server should always be running, otherwise it will not become a "service", so we want to let the server side always run, the simplest way is to put the accept method in a loop.
Servers that have been running
Make a slight change to the above 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.socket (socket.af_inet, socket. SOCK_STREAM)
print ' Socket created '
Try
S.bind ((HOST, PORT))
Except Socket.error, msg:
print ' Bind failed. Error Code: ' + str (msg[0]) + ' Message ' + msg[1]
Sys.exit ()
print ' Socket bind complete '
S.listen (10)
print ' Socket now listening '
#now keep talking with the client
While 1:
#wait to accept a connection-blocking call
conn, addr = S.accept ()
print ' Connected with ' + addr[0] + ': ' + str (addr[1])
data = CONN.RECV (1024)
Reply = ' OK ... ' + data
If not data:
Break
Conn.sendall (Reply)
Conn.close ()
S.close ()
It's simple just add one more while 1 statement.
Continue running the server and open another three command-line windows. Each window is connected to the server using the telnet command:
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 displays:
The code is as follows:
$ python server.py
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 the server no longer quit, OK, with CTRL + C shut down the server, all Telnet terminal will be displayed "Connection closed by foreign host."
It's pretty good, but it's too inefficient, and the server program uses loops to accept the connection and send a response, which is equivalent to a request to process one client at a time, and we ask the server to process multiple requests at the same time.
Working with multiple connections
In order to handle multiple connections, we need a separate processing code to run when the primary server receives the connection. One way is to use a thread, the server receives a connection and then creates a thread to process the connection to send and receive data, and the master server program returns to receive the new connection.
Here's how we use threads to handle connection requests:
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.socket (socket.af_inet, socket. SOCK_STREAM)
print ' Socket created '
#Bind socket to local host and port
Try
S.bind ((HOST, PORT))
Except Socket.error, msg:
print ' Bind failed. Error Code: ' + str (msg[0]) + ' Message ' + msg[1]
Sys.exit ()
print ' Socket bind complete '
#Start listening on socket
S.listen (10)
print ' Socket now listening '
#Function for handling connections. This'll be used to create threads
DEF clientthread (conn):
#Sending Message to connected client
Conn.send (' Welcome to the server. Type something and Hits enter\n ') #send only takes string
#infinite loop So, function do, terminate and thread do not end.
While True:
#Receiving from client
data = CONN.RECV (1024)
Reply = ' OK ... ' + data
If not data:
Break
Conn.sendall (Reply)
#came out of Loop
Conn.close ()
#now keep talking with the client
While 1:
#wait to accept a connection-blocking call
conn, addr = S.accept ()
print ' Connected with ' + addr[0] + ': ' + str (addr[1])
#start new Thread takes 1st argument as a function name to being run, second is the tuple of arguments to the function.
Start_new_thread (Clientthread, (conn,))
S.close ()
Run the above service-side program and then open three terminal windows as before and execute the telent command:
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 server side of the terminal window output information as follows:
The code is as follows:
$ python server.py
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 corresponding data to the client.
This is the server-side programming we are going to cover.
Conclusion
So far, you've learned Python's basic Socket programming, and you can write some examples to strengthen that knowledge yourself.
You may encounter some problems: Bind failed. Error code:98 Message Address already in use, this problem only requires a simple change to the server port.