First, what is the socket
In the TCP/IP five layer protocol, the software program that works at the application layer wants to send its data to the computer at the other end of the network and let that computer can parse the received data to the corresponding program, and then add the header information of each layer according to the Internet protocol before the data. If this process allows the programmer to complete their own to understand how each layer of protocol works, it is very time-consuming and greatly reduce the development efficiency, so the previous to avoid this situation in the application layer and the following four layers between the socket layer. The socket layer is encapsulated in the next four layers and provides a convenient interface for developers, developers only need to follow the rules of the socket to write the program, the socket will help us to add the program data should have the next four layers of header information, so we do not have to worry about the data encapsulation.
Second, the TCP protocol socket use method
Service-Side basic format:
ImportSocketphone=socket.socket ()#To create the socket object, the default parameter is family=af_inet (network-based socket family), Type=sock_stream (using the TCP/IP protocol), you can modifyPhone.bind (('127.0.0.1', 8081))#server-bound IP and port for easy client ConnectionPhone.listen ()#listens for a client attempting to connect whiletrue:conn,addr=phone.accept ()#to establish a connection, the return value is a Da Yuanzu that contains the connection object and the client IP, the port's ancestor whileTrue:Try: Data=CONN.RECV (1024)#receive data, bytes typeConn.send (Data.upper ())#send data, bytes type exceptException: Breakconn.close ()#Close ConnectionPhone.close ()#Close Socket
Client base format:
ImportSocketphone=socket.socket ()#creating a Socket objectPhone.connect (('127.0.0.1', 8081))#connecting to the service side whiletrue:msg=input ('>>:'). Strip ()if notMsgContinuephone.send (Msg.encode ('Utf-8'))#send data, bytes typeDATA=PHONE.RECV (1024)#receive data, bytes type Print(data)
Third, the UDP protocol socket use method
Service-Side basic format:
Import socketip_port= ('127.0.0.1', 9000) BUFSIZE=1024udp_server_client =Socket.socket (socket.af_inet,socket. SOCK_DGRAM) Udp_server_client.bind (ip_port) while True: msg,addr# The Ganso print(msg,addr) udp_server_client.sendto (Msg.upper (), addr, which receives the message from the sender and the sending end address )
Client base format:
ImportSocketip_port=('127.0.0.1', 9000) BUFSIZE=1024udp_server_client=Socket.socket (Socket.af_inet,socket. SOCK_DGRAM) whiletrue:msg=input ('>>:'). Strip ()if notMsgContinueudp_server_client.sendto (Msg.encode ('Utf-8'), Ip_port) back_msg,addr=Udp_server_client.recvfrom (BUFSIZE)Print(Back_msg.decode ('Utf-8'), addr)
Four, sticky bag
1, what is sticky bag
In the process of one or more packets of information stuck together, causing data confusion, it is important to note that the sticky packet only occurs in the TCP transmission.
2. Causes
Send side: The TCP protocol in the process of transmitting data will use an optimization algorithm, the algorithm in order to reduce the impact of network latency on the transmission of data to improve the efficiency of transmission, in a short time when multiple small packets into the system cache will be packaged together to transport the packets, which caused the sticky packet.
Receiving end: When the receiver receives data from a packet, a new packet enters the cache when it is not received, and a sticky packet may be generated.
3. Solution
1) A time interval greater than the network delay when sending small packets
2) Tell the receiver the length of the real data before sending the real data.
4. Using the struct module to customize the Transfer Protocol
1, the custom header, the format is similar to the following
head={'cmd':'put','filename': filepath,'filesize': filesize}
2. Use the JSON module to serialize the header and transcode it to bytes type for easy transmission
3. Calculate the length of the header after transcoding
4, using the struct module to encapsulate the header length information as a fixed-length bytes type data, and then sent to the receiving end
Head_pack=struct.pack ('i', Len (Head_json.encode ('utf-8' ) # converts a number to a 4-byte bytes type data
5. Send the transcoded header to the receiving end
6. Send Real data
Wu, Socketserver
Service side:
ImportSocketserverImportstructImportJSONImportOSclassFtpserver (Socketserver. Baserequesthandler):#Define your own Socketserver class, inherit Baserequesthandlercoding='Utf-8'Server_dir='File_upload'max_packet_size=1024Base_dir=os.path.dirname (Os.path.abspath (__file__)) defHandle (self):#override the handle method to handle all communication processes Print(self.request) whileTrue:data=SELF.REQUEST.RECV (4) Data_len=struct.unpack ('I', data) [0] Head_json=self.request.recv (Data_len). Decode (self.coding) Head_dic=json.loads (Head_json)#print (head_dic)cmd=head_dic['cmd'] ifhasattr (self,cmd): Func=getattr (Self,cmd) func (head_dic)defput (Self,args): File_path=Os.path.normpath (Os.path.join (self). Base_dir, Self.server_dir, args['filename'])) FileSize= args['filesize'] Recv_size=0Print('----->', File_path) with open (File_path,'WB') as F: whileRecv_size <Filesize:recv_data=self.request.recv (self.max_packet_size) f.write (recv_data) recv_size+=Len (recv_data)Print('recvsize:%s filesize:%s'%(Recv_size, filesize)) Ftpserver=socketserver. Threadingtcpserver (('127.0.0.1', 8080), ftpserver)#instantiate a server object and pass in the IP and port of the service side and the class name of the Socketserver class that you defineFtpserver.serve_forever ()#start Socketserver and run permanently
Client:
Just use the socket to
Python Network programming socket