This is a guide and tutorial for fast learning Python socket sockets programming. Python's Socket programming is similar to the C language.
Python official about Socket function please see http://docs.python.org/library/socket.html
Basically, Socket is the most basic content of any kind of computer network communication. For example, when you enter www.jb51.net in the browser's address bar, you open a socket and then connect to the Www.jb51.net 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 the 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 a Socket
The first thing to do is to create a socket,socket Socket function that can be implemented with the following code:
Copy Code code 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 '
Function Socket.socket creates a socket and returns a descriptor for the socket that can be used for other socket-related functions.
The preceding 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 throws an exception named Socket.error, which must be handled:
Copy Code code 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, suppose you've successfully created the Socket, what's the next step? Next we will use this Socket to connect to the server.
Attention:
The other types that correspond to Sock_stream are sock_dgram for UDP communication protocol, UDP communication is connectionless Socket, in this article we only discuss Sock_stream, or TCP.
Connect to Server
The server address and port number are required to connect to the server, and Www.jb51.net and port 80 are used here.
First get the IP address of the remote host
Before connecting to a remote host, we need to know its IP address, in Python, getting an IP address is simple:
Copy Code code 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.jb51.net '
Try
REMOTE_IP = Socket.gethostbyname (host)
Except Socket.gaierror:
#could not resolve
print ' Hostname could not to be resolved. Exiting '
Sys.exit ()
print ' Ip address of ' + host + ' is ' + remote_ip
We already have the IP address, then we need to specify the port to which to connect.
Code:
Copy Code code 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.jb51.net '
Port = 80
Try
REMOTE_IP = Socket.gethostbyname (host)
Except Socket.gaierror:
#could not resolve
print ' Hostname could not to be 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
Copy Code code as follows:
$ python client.py
Socket Created
Ip address of Www.jb51.net is 61.145.122.155
Socket Connected to www.jb51.net on IP 61.145.122.155
This program creates a Socket and makes a connection, so try using some other nonexistent ports (such as 81). This logic is equivalent to building a port scanner.
is connected, and then the data is sent to the server.
Friendly Tips
The concept of "connection" is only available with SOCK_STREAM/TCP sockets. A connection means a reliable data flow mechanism that can have multiple streams of data at the same time. Can be imagined as a pipeline of data that does not interfere with each other. Another important tip is that packets are sent and received in a sequential order.
Other sockets such as UDP, ICMP, and ARP do not have a "connection" concept, they are connectionless communication, meaning that you can send and receive packets from anyone or to anyone.
Send data
Sendall function is used to simply send data, we send some data to Oschina:
Copy Code code 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.jb51.net '
Port = 80
Try
REMOTE_IP = Socket.gethostbyname (host)
Except Socket.gaierror:
#could not resolve
print ' Hostname could not to be 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 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 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:
Copy Code code 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 = ' jb51.net ';
Port = 80;
Try
REMOTE_IP = Socket.gethostbyname (host)
Except Socket.gaierror:
#could not resolve
print ' Hostname could not to be 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:jb51.net\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:
Copy Code code as follows:
$ python client.py
Socket Created
Ip address of Jb51.net is 61.145.122.
Socket Connected to jb51.net on IP 61.145.122.155
Message Send successfully
http/1.1 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.jb51.net/
Jb51.net responded to the content of the URL we requested, very simple. After the data has been received, you can close the Socket.
Close socket
The close function closes the Socket:
Copy Code code as follows:
That's it.
Let's review
In the example above we have learned how to:
1. Create Socket
2. Connect to a remote server
3. Send data
4. Receive a response
When you open a www.jb51.net in a browser, the process is the same. Contains 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 incoming connections and provide data. So here www.jb51.net is the server side, and your browser is the client.
Next we start to do some coding on the server side.
Server-side programming
Server-side programming consists primarily of the following steps:
1. Open socket
2. Bind to an address and port
3. Listening for incoming connections
4. Accept Connection
5. Read and write Data
We've 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 the Socket to a specific address and port, and it requires a SOCKADDR_IN structure similar to the one required for the Connect function.
Sample code:
Copy Code code 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 binding is complete, you need to have the Socket start listening for the connection. Obviously, you can't bind two different sockets to the same port.
Connection Listening
After you bind the socket, you can start listening for the connection, and we need to turn the socket into listening mode. The listen function of the socket is used to implement the listening mode:
Copy Code code as follows:
S.listen (10)
print ' Socket now listening '
The parameters required by the Listen function become backlog, which is used to control the number of connections that can remain in standby while busy. Here we pass 10, which means that if there are 10 connections waiting to be processed, the 11th connection will be rejected. This will be clearer when the socket_accept is checked.
Accept Connection
Sample code:
Copy Code code 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:
Copy Code code as follows:
$ python server.py
Socket created
Socket bind complete
Socket now listening
Now this program is starting to wait for the connection to enter, the port is 8888, please do not close this program, we use the Telnet program to test.
Open the Command Line window and enter:
Copy Code code 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.
The server-side window displays:
Copy Code code 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 has no practical value, the connection is established generally there will be a lot of things to deal with, so let's give the client a point of response.
The Sendall function sends data to the client via an Socket:
Copy Code code 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 to run the above code, and then open another command line window to enter the following command:
Copy Code code 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 the client receiving the response from the server side.
The above example is still the same, the server-side response immediately after the exit. And some real servers like www.jb51.net are always running, accepting connection requests at all times.
That is, the server should always be in the running state, otherwise it can not become a "service", so we have to keep the server side running, the simplest way is to put the accept method in a loop.
The server that is running all the time
Make a slight change to the above code:
Copy Code code 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 to add just one more while 1 statement.
Continue running the server, and then open another three command line Windows. Each window is connected to the server using the telnet command:
Copy Code code 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 in which the server is located displays:
Copy Code code 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 terminals will display "Connection closed by foreign host."
It's pretty good, but it's too inefficient, and the server program uses loops to accept connections and send a response, which is equivalent to a request that handles up to one client at a time, and we ask the server to handle multiple requests at once.
Working with multiple connections
To handle multiple connections, we need a separate processing code to run when the primary server receives a connection. One approach is to use a thread that the server receives a connection and then creates a thread to handle the connection sending and receiving data, and then the master server program returns to receive the new connection.
Here's how we use threads to handle connection requests:
Copy Code code 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 is used to create threads
DEF clientthread (conn):
#Sending Message to connected client
Conn.send (' Welcome to the server. Type something and hit enter\n ') #send only takes string
#infinite loop So-function do not terminate and thread does 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 was run, second is the tuple of arguments to the function.
Start_new_thread (Clientthread, (conn,))
S.close ()
Run the above server-side programs, and then open three terminal windows and execute the telent command as before:
Copy Code code 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
Server-side terminal window output information is as follows:
Copy Code code 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 introduce.
Conclusion
So far, you've learned the basic programming of Python sockets, and you can write some examples to reinforce this knowledge.
You may encounter some problems: Bind failed. Error code:98 message address already in use, you just need to simply change the server port.