First, some introduction of network knowledge
The socket is the network connection endpoint. For example, when your Web browser requests a home page on www.jb51.net, your Web browser creates a socket and commands it to connect to the Www.jb51.net Web server host, and the Web server listens on a socket for requests from. Both ends use their own sockets to send and receive information.
At the time of use, each socket is bound to a specific IP address and port. An IP address is a sequence of 4 numbers, all of which are values in the range 0~255 (for example, 220,176,36,76); The value range of the port value is 0~65535. The number of ports less than 1024 is reserved for well-known network services (for example, the 80 port used by Web services); The maximum number of reservations is stored in the ipport_reserved variable of the socket module. You can also use a different port value for your program.
Not all IP addresses are visible to other parts of the world. In fact, some are reserved specifically for those non-public addresses (such as 192.168.y.z or 10.x.y.z). Address 127.0.0.1 is a native address; it always points to the current computer. Programs can use this address to connect to other programs running on the same computer.
IP address is not easy to remember, you can spend some money for a specific IP address to register a host name or domain name (such as using www.jb51.net instead of 222.76.216.16). Domain Name server (DNS) handles mapping of names to IP addresses. Each computer can have a host name, even if it is not officially registered.
How much information is transmitted over a network is based on a number of factors, one of which is the protocol used. Many protocols are based on simple, low-level protocols to form a stack of protocols. For example, the HTTP protocol, which is a protocol for communication between a Web browser and a Web server, is based on the TCP protocol and the TCP protocol is based on the IP protocol.
When you send messages between your own two programs, you typically select TCP or UDP protocols. The TCP protocol establishes a continuous connection between the two ends, and the information you send is guaranteed to reach their destinations sequentially. UDP does not establish a connection, it is fast but unreliable. The information you send may not reach the other end, or they do not arrive in order. Sometimes multiple copies of a message reach the receiving end, even if you only send it once.
Second, use the address and host name
The socket module provides several functions for working with host names and addresses.
GetHostName () returns the host name of the computer on which the program is running:
>>> Import Socket
>>> Socket.gethostname ()
' Lenovo '
gethostbyname (name) attempts to interpret the given host name as an IP address. The first check is whether the current computer can be interpreted. If not, an explanation request is sent to a remote DNS server (the remote DNS server may also forward the interpretation request to another DNS server until the request can be processed). The gethostbyname function returns this IP address or throws an exception after the lookup fails.
>>> socket.gethostbyname (' Lenovo ')
' 192.168.1.4 '
>>> socket.gethostbyname (' www.jb51.net ')
' 222.76.216.16 '
The form of an extension is GETHOSTBYNAME_EX (name), which returns a tuple of three elements, which is the primary hostname of the given address, a list of optional host names for the same IP address, A list of other IP addresses for the same interface of the same host (the list may be empty).
>>> socket.gethostbyname (' www.163.com ')
' 60.191.81.49 '
>>> socket.gethostbyname_ex (' www.163.com ')
(' www.cache.split.netease.com ', [' www.163.com '], [' 60.191.81.48 ', ' 60.191.81.49
, ' 60.191.81.50 ', ' 60.191.81.51 ', ' 60.191.81.52 ', ' 60.191.81.53 ', ' 60.191.81.54
, ' 220.181.28.50 ', ' 220.181.28.51 ', ' 220.181.28.52 ', ' 220.181.28.53 ', ' 220.181.
8.54 ', ' 220.181.31.182 ', ' 220.181.31.183 ', ' 220.181.31.184 ']
The GETHOSTBYADDR function is the same as the GETHOSTBYNAME_EX, except that the argument you give it is an IP address string:
>>> socket.gethostbyaddr (' 202.165.102.205 ')
(' homepage.vip.cnb.yahoo.com ', [' www.yahoo.com.cn '], [' 202.165.102.205 '])
The Getservbyname (service,protocol) function requires a service name (such as ' Telnet ' or ' ftp ') and a protocol (such as ' TCP ' or ' UDP ') to return the port number used by the service:
>>>socket.getservbyname (' http ', ' TCP ')
80
>>>socket.getservbyname (' telnet ', ' TCP ')
23
Typically, non-Python programs store and use IP addresses in the form of 32-byte packets. Inet_aton (IP_ADDR) and Inet_ntoa (packed) functions are converted in this form and the IP address:
>>> Socket.inet_aton (' 222.76.216.16 ')
' \xdel\xd8\x10 '
>>> socket.inet_ntoa (' \xdel\xd8\x10 ')
' 222.76.216.16 '
The socket also defines a number of variables to represent the reserved IP address. Inaddr_any and inaddr_broadcast are reserved IP addresses that represent arbitrary IP addresses and broadcast addresses, and inaddr_loopback represent loopback devices, always address 127.0.0.1. These variables are in the form of 32-byte digits.
The Getfqdn ([name]) function returns a full domain name for a given host name (if omitted, returns the entire domain name of this machine).
Third, the use of low-level socket communication
Although Python provides some encapsulation that makes it easier to use a socket, you can also work directly with the socket.
1. Create and Destroy sockets
The socket (Family,type[,proto]) function in the socket module creates a new socket object. The family value is usually af_inet. The value of type is usually Sock_stream (for directed connections, reliable TCP connections) or SOCK_DGRAM (for UDP):
>>> from Socket Import *
>>> S=socket (Af_inet,sock_stream)
The family and type parameters imply a protocol, but you can use the third optional parameter of the socket (proto such as ipproto_tcp or Ipproto_raw) to specify the protocol used. Instead of using the IPPROTO_XX variable, you can use the function Getprotobyname:
>>> getprotobyname (' TCP ')
6
>>> ipproto_tcp
6
FROMFD (Fd,type[,proto]) is a function that is rarely used to create a socket object from an open file descriptor (the file descriptor is returned by the file's Fileno () method). The file descriptor is connected to a real socket, not a file. The Fileno () method of the Socket object returns a file descriptor about the socket.
When you use the finished socket object, you should call the close () method to explicitly shut down the socket to free up resources as soon as possible (although the socket is automatically closed when it is reclaimed by the garbage collector). Alternatively, you can use the shutdown (how) method to close the side or both sides of the connection. Parameter 0 prevents the socket from receiving data, 1 blocks sending, and 2 blocks receiving and sending.
2. Connect socket
When two sockets are connected (for example, using TCP), one end listens for and receives incoming connections, and the other end initiates a connection. The pro listening side creates a socket, invokes the bind (address) function to bind a particular location and port, invokes the listen (backlog) incoming connection, and finally calls accept () to receive the new, incoming connection, following the server-side code:
>>> S=socket (Af_inet,sock_stream)
>>> s.bind (' 127.0.0.1 ', 44444)
>>> S.listen (1)
>>> q,v=s.accept () #返回socket Q and Address V
Note: The above code will remain waiting until the connection is established. Let's open another Python interpreter as the client, and then type the following code:
>>> from Socket Import *
>>> S=socket (Af_inet,sock_stream)
>>> s.connect (' 127.0.0.1 ', 44444) #发起连接
OK, let's verify that the connection is established. On the server side, we type the following code to send a message:
>>> q.send (' Hello,i come from pythontik.com ') Note: sometimes send () argument 1 must be string or buffer,not str errors may occur because Your machine does not support the UTF-8 character set, and the temporary solution is q.send (b ' Hello ... ')
#发送的字节数
Type the following code on the client to receive the information:
>>> S.RECV (1024)
' Hello,i come from pythontik.com '
The address you pass to bind and connect is a tuple of af_inet sockets (Ipaddress,port). Instead of connect, you can also call the CONNECT_EX (address) method. If the call to C on the back returns an error, then CONNECT_EX will also return an error (otherwise return 0 represents success) instead of throwing an exception.
When you call listen, you give it a parameter that represents the total number of incoming connections that are allowed to be placed in the wait queue. When the wait queue is full, if more connections arrive, the remote side will be told that the connection is denied. The somaxconn variable in the socket module indicates the maximum amount that can be accommodated by the waiting queue.
The Accept () method returns an address that is shaped like bind and connect, representing the address of a remote socket. The value of the variable v is shown below:
>>> V
(' 127.0.0.1 ', 1334)
UDP is a disconnected connection, but you can still use the given destination address and port to call connect to associate a socket.
3. Send and receive data
function Send (String[,flags]) sends a given string to a remote socket. SendTo (string[,flags],address) sends the given string to a specific address. Typically, the Send method is used for the Socket,sendto method of a reliable connection for sockets that are not connected, but if you are up in a UDP socket using connect to make it connected to a specific target, Then you can also use the Send method instead of SendTo.
Both send and sendto return the actual number of bytes sent. When you send a lot of data quickly, you may want to make sure that all the information has been sent, so you can use one of the following functions:
def safesend (sock,msg):
Sent=0
While msg:
I=sock.send (msg)
If I==-1: #发生了错误
Return-1
Sent+=i
Msg=msg[i:]
Time.sleep (25)
Return sent
The recv (Bufsize[,flags]) method receives a incoming message. If a large amount of data is waiting, it returns only the previous bufsize byte number of data. Recvfrom (Bufsize[,flags]) does the same thing except that it uses the AF_INET socket's return value (data, (Ipaddress,port)), which makes it easy for you to know where the message comes from (this is useful for disconnected sockets).
The Send,sendto,recv and Recvfrom methods all have an optional parameter flags, the default value is 0. You can pass on the socket. The msg_* variable is combined (bitwise OR) to create the value of the flags. These values vary by platform, but the most common values are as follows:
Msg_oob: Handles Out-of-band data (both TCP emergency data).
Msg_dontroute: Do not use the routing table, send directly to the interface.
Msg_peek: Returns the waiting data and does not remove them from the queue.
For example, if you have an open socket and it has a message waiting to be received, you can receive the message and do not remove it from the queue of incoming data:
>>> Q.recv (1024,msg_peek)
' Hello '
>>> q.recv (1024,msg_peek) #因为没有删除, so you can get it again.
' Hello '
The makefile ([Mode[,bufsize]] method returns a file class object that encapsulates the socket so that you can later pass it to the code that requires the parameter to be a file (perhaps you prefer to use the file method instead of send and recv). This optional mode and bufsize parameter is the same as the built-in open function.
4. Use socket option
Both the Getpeername () and GetSockName () methods of the socket object return a two-tuple containing an IP address and port (this two-tuple form is as you pass to connect and bind). Getpeername returns the address and port of the connected remote socket, GETSOCKNAME returns the same information about the local socket.
By default, the socket is blocked, meaning that the call to the method of the socket is not returned until the task completes. For example, if the cache of outgoing data is full and you attempt to send more data, your call to send will be blocked until it can put more data into the cache. You can change this default behavior by calling the Setblocking (flag) method (where flag values are 0,setblocking (0)) to make the socket non-blocking. When the socket is non-blocking, an error exception can result if the action is blocked. The following code will attempt to continuously accept new connections and use function ProcessRequest to handle them. If a new connection is not valid, it will try again in half a second interval. Another method is to check the arrival of a new connection by using Select or poll on your listening socket.
Options for other sockets can be set and retrieved using the setsockopt (Level,name,value) and getsockopt (Level,name[,buflen) methods. The socket represents a different layer of a protocol stack, and the level parameter specifies which layer the option applies to. The level's value begins with the Sol_ (SOL_SOCKET,SOL_TCP, and so on). Name indicates which option you are dealing with. For value, if this option requires a numeric value, value can only pass in numeric values. You can also pass in a cache (a string), but you must use the correct format. For getsockopt, not specifying the Buflen parameter means that you require a numeric value and return that value. If you provide a buflen,getsockopt return representing a cached string, its maximum length is the number of Buflen bytes. The following example sets a socket for sending a cache size of 64KB:
>>> S=socket (Af_inet,sock_stream)
>>> s.setsockopt (sol_socket,so_sndbuf,65535)
To get the life cycle (TTL) and hop count that a package can have before it is routed, you can use the following code:
>>> s.getsockopt (SOL_IP,IP_TTL)
32
5. Numerical conversion
Because the byte order of different platforms is not the same, we use the standard network byte order when transferring data across the network. The Nthol (x) and Ntohs (x) functions require a numeric value of a network byte order and convert it to the same number as the current host byte order, whereas htonl (x) and htons (x) are the opposite:
>>> Import.socket
>>> socket.htons (20000) #转换为一个16位的值
8270
>>> socket.htonl (20000) #转换为一个32位的值
541982720
>>> Socket.ntohl (541982720)
20000
Using Socketservers
The Socketservers module defines a base class for a set of socket service classes that compresses and hides the details of listening, accepting, and processing incoming socket connections.
1. Socketservers Family
TCPServer and Udpserver are socketserver subclasses that handle both TCP and UDP information.
Note: Socketserver also provides unixstreamserver (TCPServer subclasses) and Unixdatagramserver (Udpserver subclasses), which are like their parent class except when using AF when creating a listening socket _unix replaced the af_inet.
By default, the socket service processes one connection at a time, but you can use the ThreadingMixIn and Forkingmixin classes to create any socketserver threads and child processes. In fact, the Socketserver module provides some useful classes to solve your problems, they are: Forkingudpserver, Forkingtcpserver, Threadingudpserver, Threadingtcpserver, Threadingunixstreamserver and Threadingunixdatagramserver.
Socketserver to handle incoming connections in the usual way; to make it more useful, you should provide your own request processor class to it so that it passes a socket to handle it. The Baserequesthandler class in the Socketserver module is the parent class for all request processors. Suppose, for example, that you need to write a multithreaded email server, first you want to create a mailrequesthandler, it's a subclass of Baserequesthandler, and then pass it to a newly created socketserver:
Import Socketserver
. #创建你的MailRequestHandler
Addr= (' 220.172.20.6 ',) #监听的地址和端口
Server=socketserver.threadingtcpserver (Addr,mailrequesthandler)
Server.serve_forever ()
Each time a new connection arrives, the server creates a new Mailrequesthandler instance and calls its handle () method to handle the new request. Because the server inherits from Threadingtcpserver, for each new request it initiates a separate thread to process the request so that multiple requests can be processed concurrently. If you replace Server_forever with Handle_request (), it handles the connection request one by one. Server_forever just repeated calls to Handle_request.
Generally, you just use one of the socket services, but if you need to create your own subclass, you can customize it by overwriting the methods we've mentioned below.
When the service is first created, the __INIT__ function calls the Server_bind () method to bind the listening socket (self.socket) to the correct address (self.server_address). The Server_activate () is then invoked to activate the service (by default, the Listen method of the socket is invoked).
This socket service does nothing until it calls the Handle_request or Serve_forever method. Handle_request calls Get_request () to wait and receive a new socket connection, and then calls Verify_request (request,client_address) to see if the service will handle the connection ( You can use this in Access control, and verify_request always returns true by default. If this request is processed, handle_request then calls Process_request (request,client_address) if Process_request (request,client_address) If an exception is caused, the Handle_error (request,client_address) is invoked. By default, Process_request simply calls Finish_request (request,client_address), and the subprocess and thread classes override this behavior to start a new process or thread, and then invoke Finish_request. Finish_request instantiates a new request processor, requesting that the processor take turns calling their handle () method.
When Socketserver creates a new request processor, it passes to the self variable of the processor's __init__ function so that the processor can access information about the service.
The Socketserver Fileno () method returns the file descriptor that listens for the socket. The address_family member variable specifies the socket family (such as af_inet) that listens on the socket, and Server_address contains the address on which the socket is being bound. The socket variable contains the listening socket itself.
2. Request processor
The request processor has the setup (), handle () and finish () methods that you can override to customize your own behavior. In general, you only need to overwrite the handle method. The Baserequesthandler __init__ function calls the Setup () method to initialize the work, handle () serves the request, finish () is used to perform the cleanup, if handle or setup causes an exception, Finish will not be invoked. Remember, your request processor will create a new instance for each request.
The request member variable has the recently accepted socket for the stream (TCP) service; For datagram services, it is a tuple that contains incoming messages and a listening socket. Client_address contains the sender's address, and the server has a reference to Socketserver (through which you can access its members, such as Server_address).
The following example implements a Echorequesthandler, which, as a server, sends the data sent by the client back to the client:
>>> Import Socketserver
>>> class Echorequesthandler (Socketserver.baserequesthandler):
... def handle (self):
... print ' Got new connection! '
. While 1:
... mesg=self.request.recv (1024)
. If not msg:
.. break
... print ' Received: ', msg
... self.request.send (msg)
... print ' Done with connection '
>>> server=socketserver.threadingtcpserver ((' 127.0.0.1 ', 12321), Echoreuesthandler)
>>> server.handle_request () #执行后将等待连接
Got New connection!
Received:hello!
Received:i like tuesdays!
Done with connection
Open another Python interpreter as the client, and then execute the following code:
>>> from Socket Import *
>>> S=socket (Af_inet,sock_stream)
>>> s.connect (' 120.0.0.1 ', 12321)
>>> s.send (' hello! ')
6
>>> Print S.RECV (1024)
Hello!
>>> s.send (' I like tuesdays! ')
16
>>> Print S.RECV (1024)
I like tuesdays!
>>> S.close ()
The Socketserver module also defines two subclasses of the Baserequesthandler: Streamrequesthandler and Datagramrequesthandler. They cover the setup and Finish methods and create two file objects Rfile and Wfile, and you can use these two file objects to read and write data to the client instead of using the socket method.
Blocking or synchronous programming of sockets
First, the use of sockets
The most basic part of network programming is the socket (socket). There are two types of sockets: The server socket and the client socket. After you create a server socket, you tell it to wait for the connection. It then listens to a network address (like: xxx.xxx.xxx.xxx:xxx) until the client connects. Then the two ends can be communicated.
Processing client sockets is usually easier than processing a service socket, because the server must be prepared to handle the connection from the client at all times, and it must handle multiple connections, and the client needs to simply connect, then do something, and then disconnect.
When instantiating a socket, you can specify three parameters: Address series (default socket.af_inet), stream socket (this is the default value: Socket. SOCK_STREAM) or datagram socket (Socket.sock_dgram), protocol (default value is 0). For simple sockets, you can use the default values without specifying any parameters.
The server socket calls the Listen method after using the Bind method to listen for a given address. The client socket can then connect to the server by using the Connect method (the address parameter used by the Connect method is the same as bind). The Listen method requires a parameter, which is the number of connections that can be included in the waiting connection queue.
Once the service socket calls the Listen method, it goes into the pro listening State, and then usually uses an infinite loop: 1, start accepting the connection from the guest room, which is implemented by calling the Accept method. When this method is invoked, it will be blocked (waiting for the client to initiate the connection) until a client connects, and after the connection, accept returns a tuple of the form (client,address), where the client is a socket for communicating with clients. The address is a client-shaped xxx.xxx.xxx.xxx:xxx, 2, and then the server handles the client's request, 3, and then calls 1 after processing completes.
For data transfer, there are two ways to socket: send and recv. Send sends data using string arguments; The recv parameter is the number of bytes, indicating the amount of data received at a time, preferably 1024 if you are unsure of the amount of data you should accept.
An example of a minimal server/client is given below:
Service side:
Import socket
s = Socket.socket ()
Host = Socket.gethostname ()
Port = 1234
S.bind (host, Port)
S.listen (5)
While True:
C, addr = S.accept ()
print ' Got connection from ', addr
C.send (' Thank for connecting ')
C.close ()
Client:
Import socket
s = Socket.socket ()
Host = Socket.gethostname ()
Port = 1234
S.connect (host, Port)
Print S.RECV (1024)
Note: If you use CTRL-C to stop the server, you may need to wait a while to use the same port again.
Ii. Use of Socketserver
The Socketserver module simplifies the task of writing a Web server.
It provides four basic service classes: TCPServer (using the TCP protocol), Udpserver (using datagrams), Unixstreamserver,
Unixdatagramserver. Unixstreamserver and unixdatagramserver are used on Unix-like platforms.
All four class processing requests use a synchronized method, that is, the current request processing must be completed before the next request processing begins
。
It takes four steps to create a server with Socketserver:
1. Create a request processor class using the subclass Baserequesthandler class and the handle () method that overrides it to process the incoming
's request;
2, the instantiation service class such as TCPServer, and passes to it the parameter: the server address and the request processor class;
3, invoke the Handle_request () or Serve_forever () method of the service instance object to process the request.
The following uses Socketserver to write a simplest server in a synchronized way:
From Socketserver import TCPServer, Streamrequesthandler
#第一步. Where the Streamrequesthandler class is a subclass of the Baserequesthandler class, which defines a stream socket
#rfile和wfile方法
Class Handler (Streamrequesthandler):
def handle (self):
addr = Self.request.getpeername ()
print ' Got connection from ', addr
Self.wfile.write (' Thank for connecting ')
#第二步. Where ' represents the host running the server
Server = TCPServer ((', 1234), Handler)
#第三步. Serve_forever () causes the loop state to enter
Server.serve_forever ()
Note: You can connect to only one client at a time by using a blocking or synchronizing method before you can connect to the next client after processing is complete.
Non-blocking or asynchronous programming
Current 1/2 page
12 Next read the full text