Python Network Programming Supplement

Source: Internet
Author: User
Tags hmac unpack osclass

FTP jobs: uploading and downloading files

Service Side
Import socketimport structimport jsonimport subprocessimport osclass mytcpserver:address_family = Socket.AF_INET So Cket_type = socket. Sock_stream allow_reuse_address = False max_packet_size = 8192 coding= ' utf-8 ' request_queue_size = 5 server  _dir= ' File_upload ' def __init__ (self, server_address, bind_and_activate=true): "" "Constructor.        May is extended, do not override. "" "                                    Self.server_address=server_address Self.socket = Socket.socket (self.address_family, Self.socket_type) if Bind_and_activate:try:self.server_bind () Self.s        Erver_activate () Except:self.server_close () Raise Def server_bind (self):        "" "called by constructor to bind the socket. "" "If self.allow_reuse_address:self.socket.setsockopt (socket. Sol_socket, SOCKET.     SO_REUSEADDR, 1) self.socket.bind (self.server_address)   Self.server_address = Self.socket.getsockname () def server_activate (self): "" "called by constructor to Activa        Te the server.         "" "Self.socket.listen (self.request_queue_size) def server_close (self):" "" Called to clean-up the server. "" "Self.socket.close () def get_request (self):" "" Get the request and client address from the SOC        Ket. "" "Return Self.socket.accept () def close_request (self, request):" "called        Uest. "" " Request.close () def run (self): while True:self.conn,self.client_addr=self.get_request () p Rint (' From client ', self.client_addr) while True:try:head_struct = Self.con                    N.RECV (4) if not head_struct:break Head_len = struct.unpack (' i ', head_struct) [0] Head_json = Self.conn.recv (Head_len). Decode (self.coding) head_dic = Json.loads (head_json) print (head_dic) #head_dic ={' cmd ': ' Put ', ' filename ': ' A.tx                        T ', ' filesize ': 123123} cmd=head_dic[' cmd ' if Hasattr (self,cmd):    Func=getattr (Self,cmd) func (head_dic) except Exception:break def put (Self,args): File_path=os.path.normpath (Os.path.join (Self.server_dir, args[' Filena Me ']) filesize=args[' filesize ' recv_size=0 print ('-----> ', File_path) with open (fi Le_path, ' WB ') as F:while recv_size < Filesize:recv_data=self.conn.recv (self.max_packet_size ) F.write (Recv_data) Recv_size+=len (recv_data) print (' recvsize:%s filesize:%s '% (recv_size,filesize)) Tcpserver1=mytcpserver ((' 127.0.0.1 ', 8080)) Tcpserver1.run () #下列代码与本题无关class myudpserver: "" "    UDP server class. "" " Address_family = socket.af_inet Socket_type = socket. Sock_dgram allow_reuse_address = False max_packet_size = 8192 coding= ' utf-8 ' def get_request (self): dat A, client_addr = Self.socket.recvfrom (self.max_packet_size) return (data, Self.socket), Client_addr def server_a        Ctivate (self): # need-to-call listen () for UDP.        Pass Def shutdown_request (self, request): # need to shutdown anything.        Self.close_request (Request) def close_request (self, request): # need to close anything. Pass
Client
Import socketimport structimport jsonimport osclass mytcpclient:address_family = socket.af_inet Socket_type = Socke T.sock_stream allow_reuse_address = False max_packet_size = 8192 coding= ' utf-8 ' request_queue_size = 5 def __init__ (self, server_address, connect=true): self.server_address=server_address self.socket = Socket.socket                (self.address_family, Self.socket_type) if Connect:try: Self.client_connect () Except:self.client_close () Raise Def client_connect ( Self): Self.socket.connect (self.server_address) def client_close (self): Self.socket.close () def run (SE             LF): While True:inp=input ("&GT;&GT;:"). Strip () if not inp:continue l=inp.split () Cmd=l[0] If Hasattr (self,cmd): Func=getattr (Self,cmd) func (l) def Put (Self,args): CMd=args[0] filename=args[1] if not os.path.isfile (filename): print (' file:%s are NOT exists '%filen AME) return else:filesize=os.path.getsize (filename) head_dic={' cmd ': cmd, ' filename ': OS . Path.basename (filename), ' filesize ': filesize} print (Head_dic) head_json=json.dumps (head_dic) head_jso N_bytes=bytes (head_json,encoding=self.coding) head_struct=struct.pack (' I ', Len (head_json_bytes)) Self.socket.            Send (Head_struct) self.socket.send (head_json_bytes) send_size=0 with open (filename, ' RB ') as F: For line F:self.socket.send (line) Send_size+=len (line) print (Send_si Ze) else:print (' upload successful ') client=mytcpclient ((' 127.0.0.1 ', 8080)) Client.run ()
Link legitimacy for a certified client

If you want to implement a simple client link authentication function in a distributed system, and not as complex as SSL, then use hmac+ to add salt to achieve

Service Side
#_ *_coding:utf-8_*___author__ = ' Linhaifeng ' from socket import *import hmac,ossecret_key=b ' Linhaifeng Bang Bang Bang '    DEF Conn_auth (conn): "Authenticated client link:P Aram Conn:: Return: ' ' Print (' start verifying the legitimacy of new links ') Msg=os.urandom (32) Conn.sendall (msg) h=hmac.new (secret_key,msg) digest=h.digest () Respone=conn.recv (Len (Digest)) return hmac.com        Pare_digest (respone,digest) def data_handler (conn,bufsize=1024): If not Conn_auth (conn): Print (' The link is illegal, off ')        Conn.close () return print (' link valid, start communication ') while TRUE:DATA=CONN.RECV (bufsize) if not data:break Conn.sendall (Data.upper ()) def Server_handler (ip_port,bufsize,backlog=5): "Handles only links:p Aram Ip_port:: RET urn: "' Tcp_socket_server=socket (af_inet,sock_stream) tcp_socket_server.bind (ip_port) tcp_socket_server.liste        N (backlog) while true:conn,addr=tcp_socket_server.accept () print (' New connection [%s:%s] '% (addr[0],addr[1]) Data_handler (conn,bufsize) if __name__ = = ' __main__ ': ip_port= (' 127.0.0.1 ', 9999) bufsize=1024 Server_handler (ip_port,bufsize) 
Client (legal)
#_ *_coding:utf-8_*___author__ = ' Linhaifeng ' from socket import *import hmac,ossecret_key=b ' Linhaifeng Bang Bang Bang ' DEF Conn_auth (conn):    "    Verify client-to-server link    :p Aram Conn:    : return:    '    msg=conn.recv    ' h= Hmac.new (secret_key,msg)    digest=h.digest ()    Conn.sendall (Digest) def Client_handler (ip_port,bufsize=1024 ):    tcp_socket_client=socket (Af_inet,sock_stream)    tcp_socket_client.connect (ip_port)    Conn_auth ( tcp_socket_client) while    True:        data=input (' >>: '). Strip ()        if not data:continue        if data = = ' Quit ': Break        Tcp_socket_client.sendall (Data.encode (' Utf-8 '))        respone=tcp_socket_client.recv (bufsize)        Print (Respone.decode (' Utf-8 '))    tcp_socket_client.close () if __name__ = = ' __main__ ':    ip_port= (' 127.0.0.1 ', 9999)    bufsize=1024    Client_handler (ip_port,bufsize)
Client (illegal: Do not know encryption method)
#_ *_coding:utf-8_*___author__ = ' Linhaifeng ' from socket import *def Client_handler (ip_port,bufsize=1024):    tcp_ Socket_client=socket (Af_inet,sock_stream)    Tcp_socket_client.connect (ip_port) while    True:        data=input (' >>: '). Strip ()        if not data:continue        if data = = ' quit ': Break        Tcp_socket_client.sendall ( Data.encode (' Utf-8 '))        respone=tcp_socket_client.recv (bufsize)        print (Respone.decode (' Utf-8 '))    TCP _socket_client.close () if __name__ = = ' __main__ ':    ip_port= (' 127.0.0.1 ', 9999)    bufsize=1024    Client_ Handler (ip_port,bufsize)
Client (illegal: do not know Secret_key)
#_ *_coding:utf-8_*___author__ = ' Linhaifeng ' from socket import *import hmac,ossecret_key=b ' Linhaifeng Bang Bang bang1111 ' Def conn_auth (conn):    '    Verify client-to-server links    :p Aram Conn:    : ' Return: ' '    msg=conn.recv (    h=hmac.new (secret_key,msg)    digest=h.digest ()    Conn.sendall (Digest) def Client_handler (Ip_port, bufsize=1024):    tcp_socket_client=socket (Af_inet,sock_stream)    tcp_socket_client.connect (ip_port)    Conn_auth (tcp_socket_client)    while True:        data=input (' >>: '). Strip ()        if not data:continue        if data = = ' quit ': Break        Tcp_socket_client.sendall (Data.encode (' Utf-8 '))        respone=tcp_socket_ CLIENT.RECV (bufsize)        print (Respone.decode (' Utf-8 '))    tcp_socket_client.close () if __name__ = = ' __main__ ':    ip_port= (' 127.0.0.1 ', 9999)    bufsize=1024    Client_handler (ip_port,bufsize)
 Two Socketserver implementation concurrency

TCP-based sockets, the key is two loops, a link loop, a communication loop

There are two main classes in the Socketserver module: the server class (solve the link problem) and the request class (to solve the communication problem)

Server class:

Request class:

Inheritance Relationship:

Take the following code as an example to analyze Socketserver Source:

Ftpserver=socketserver. Threadingtcpserver ((' 127.0.0.1 ', 8080), ftpserver)
Ftpserver.serve_forever ()

Order of Lookup properties: Threadingtcpserver->threadingmixin->tcpserver->baseserver

    1. Instantiate get Ftpserver, first find class Threadingtcpserver __init__, found in TCPServer, and then execute server_bind,server_active
    2. Find Ftpserver under the Serve_forever, found in Baseserver, and then execute Self._handle_request_noblock (), the method is also in the Baseserver
    3. Executes Self._handle_request_noblock () and then executes the request, client_address = Self.get_request () (which is self.socket.accept in TCPServer ( ), and then execute self.process_request (Request, client_address)
    4. Find Process_request in ThreadingMixIn, turn on multithreading to handle concurrency, and execute Process_request_thread, execute self.finish_request (request, Client_ Address
    5. The above four parts completed the link loop, this section began to enter the processing of the communication section, found in the Baseserver finish_request, triggering our own definition of the class instantiation, to find __init__ method, and our own definition of the class does not have the method, Then go to its parent class, which is baserequesthandler ....

SOURCE Analysis Summary:

TCP-based socketserver in our own defined class.

    1. Self.server is a Socket object
    2. Self.request is a link
    3. Self.client_address is the client address

UDP-based socketserver in our own defined class.

    1. Self.request is a tuple (the first element is the data sent by the client, the second part is the UDP socket object on the server), such as (b ' adsf ', <socket.socket fd=200, family=addressfamily.af_ INET, Type=socketkind.sock_dgram, proto=0, laddr= (' 127.0.0.1 ', 8080) >)
    2. Self.client_address is the client address

Ftpserver
Import socketserverimport structimport jsonimport osclass ftpserver (socketserver. Baserequesthandler): coding= ' utf-8 ' server_dir= ' file_upload ' max_packet_size=1024 base_dir=os.path.dirname (OS. Path.abspath (__file__)) def handle (self): print (self.request) while True:data=self.request.re            CV (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 '] if Hasatt  R (Self,cmd): Func=getattr (Self,cmd) func (head_dic) def put (Self,args): File_path = Os.path.normpath (Os.path.join (self). Base_dir, Self.server_dir, args[' filename ')) filesize = args[' filesize '] recv _size = 0 Print ('-----> ', File_path) with open (File_path, ' WB ') as F:while Recv_size < fil           Esize:     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) Ftpserver.serve_forever ()
ftpclient
Import socketimport structimport jsonimport osclass mytcpclient:address_family = socket.af_inet Socket_type = Socke T.sock_stream allow_reuse_address = False max_packet_size = 8192 coding= ' utf-8 ' request_queue_size = 5 def __init__ (self, server_address, connect=true): self.server_address=server_address self.socket = Socket.socket                (self.address_family, Self.socket_type) if Connect:try: Self.client_connect () Except:self.client_close () Raise Def client_connect ( Self): Self.socket.connect (self.server_address) def client_close (self): Self.socket.close () def run (SE             LF): While True:inp=input ("&GT;&GT;:"). Strip () if not inp:continue l=inp.split () Cmd=l[0] If Hasattr (self,cmd): Func=getattr (Self,cmd) func (l) def Put (Self,args): CMd=args[0] filename=args[1] if not os.path.isfile (filename): print (' file:%s are NOT exists '%filen AME) return else:filesize=os.path.getsize (filename) head_dic={' cmd ': cmd, ' filename ': OS . Path.basename (filename), ' filesize ': filesize} print (Head_dic) head_json=json.dumps (head_dic) head_jso N_bytes=bytes (head_json,encoding=self.coding) head_struct=struct.pack (' I ', Len (head_json_bytes)) Self.socket.            Send (Head_struct) self.socket.send (head_json_bytes) send_size=0 with open (filename, ' RB ') as F: For line F:self.socket.send (line) Send_size+=len (line) print (Send_si Ze) else:print (' upload successful ') client=mytcpclient ((' 127.0.0.1 ', 8080)) Client.run ()

Python Network programming supplement

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.