zoukankan      html  css  js  c++  java
  • Python网络编程学习_Day9

    一、socketserver实现多并发

    socket只能实现单进程通讯,要实现多进程同时和服务端通讯就要使用socketserver。

    代码如下:

    1 import socket
    2 client = socket.socket()
    3 client.connect(("localhost",9000))
    4 while True:
    5     choice = input(">>>:")
    6     if len(choice) == 0:continue
    7     client.send(choice.encode())
    8     recv = client.recv(1024)
    9     print("recved:",recv.decode())
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 # Author:Liumj
     4 import socketserver
     5 class MyTCPHandler(socketserver.BaseRequestHandler):
     6     def handle(self):
     7         while True:
     8             self.data = self.request.recv(1024).strip()
     9             print(self.client_address[0])
    10             print(self.data)
    11             self.request.sendall(self.data.upper())
    12 if __name__ =="__main__":
    13     HOST,PORT = "localhost",9000
    14     server = socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)
    15     server.serve_forever()

     二、FTP程序开发

    1.服务端代码

      1 import socketserver
      2 import configparser
      3 from conf import settings
      4 import os
      5 import hashlib
      6 import time
      7 t = time.strftime("%H_%M_%S")
      8 
      9 STATUS_CODE  = {
     10     250 : "Invalid cmd format, e.g: {'action':'get','filename':'test.py','size':344}",
     11     251 : "Invalid cmd ",
     12     252 : "Invalid auth data",
     13     253 : "Wrong username or password",
     14     254 : "Passed authentication",
     15     255 : "Filename doesn't provided",
     16     256 : "File doesn't exist on server",
     17     257 : "ready to send file",
     18     258 : "md5 verification",
     19 }
     20 import json
     21 class FTPHandler(socketserver.BaseRequestHandler):
     22     def handle(self):
     23         while True:
     24             self.data = self.request.recv(1024).strip()
     25             print(self.client_address[0])
     26             print(self.data)
     27             if not self.data:
     28                 print("client closed...")
     29                 break
     30             data  = json.loads(self.data.decode())
     31             if data.get('action') is not None:
     32                 print("---->",hasattr(self,"_auth"))
     33                 if hasattr(self,"_%s"%data.get('action')):
     34                     func = getattr(self,"_%s"% data.get('action'))
     35                     func(data)
     36                 else:
     37                     print("invalid cmd")
     38                     self.send_response(251)
     39             else:
     40                 print("invalid cmd format")
     41                 self.send_response(250)
     42 
     43     def send_response(self,status_code,data=None):
     44         '''向客户端返回数据'''
     45         response = {'status_code':status_code,'status_msg':STATUS_CODE[status_code]}
     46         if data:
     47             response.update( data  )
     48         self.request.send(json.dumps(response).encode())
     49 
     50     def _auth(self,*args,**kwargs):
     51         data = args[0]
     52         if data.get("username") is None or data.get("password") is None:
     53             self.send_response(252)
     54 
     55         user =self.authenticate(data.get("username"),data.get("password"))
     56         if user is None:
     57             self.send_response(253)
     58         else:
     59             print("passed authentication",user)
     60             self.user = user
     61             self.send_response(254)
     62     def authenticate(self,username,password):
     63         '''验证用户合法性,合法就返回用户数据'''
     64 
     65         config = configparser.ConfigParser()
     66         config.read(settings.ACCOUNT_FILE)
     67         if username in config.sections():
     68             _password = config[username]["Password"]
     69             if _password == password:
     70                 print("pass auth..",username)
     71                 config[username]["Username"] = username
     72                 return config[username]
     73 
     74     def _put(self,*args,**kwargs):
     75         "client send file to server"
     76         data = args[0]
     77         # if data.get('filename') is None:
     78         #     self.send_response(255)
     79         user_home_dir = "%s/%s" % (settings.USER_HOME, self.user["Username"])
     80         file_abs_path = "%s/%s" % (user_home_dir, data.get('filename'))
     81         print("file abs path", file_abs_path)
     82         print("server.....")
     83         self.send_response(257)
     84         received_size = 0
     85         total_size = int(self.request.recv(1024))
     86         file_obj = open(file_abs_path+t, "wb")
     87         #print("zhaodao.....")
     88         while received_size < total_size:
     89             data = self.request.recv(4096)
     90             received_size +=len(data)
     91             file_obj.write(data)
     92         else:
     93             print("---recv done...")
     94             file_obj.close()
     95 
     96     def _get(self,*args,**kwargs):
     97         data = args[0]
     98         if data.get('filename') is None:
     99             self.send_response(255)
    100         user_home_dir = "%s/%s" %(settings.USER_HOME,self.user["Username"])
    101         file_abs_path = "%s/%s" %(user_home_dir,data.get('filename'))
    102         print("file abs path",file_abs_path)
    103 
    104         if os.path.isfile(file_abs_path):
    105             file_obj = open(file_abs_path,"rb")
    106             file_size = os.path.getsize(file_abs_path)
    107             self.send_response(257,data={'file_size':file_size})
    108             self.request.recv(1) #等待客户端确认
    109 
    110             if data.get('md5'):
    111                 md5_obj = hashlib.md5()
    112                 for line in file_obj:
    113                     self.request.send(line)
    114                     md5_obj.update(line)
    115                 else:
    116                     file_obj.close()
    117                     md5_val = md5_obj.hexdigest()
    118                     self.send_response(258,{'md5':md5_val})
    119                     print("send file done....")
    120             else:
    121                 for line in file_obj:
    122                     self.request.send(line)
    123                 else:
    124                     file_obj.close()
    125                     print("send file done....")
    126         else:
    127             self.send_response(256)
    128 
    129     def _ls(self,*args,**kwargs):
    130         pass
    131 
    132     def _cd(self, *args, **kwargs):
    133         pass
    134 
    135 if __name__ == "__main__":
    136     HOST, PORT = "localhost", 9000
    ftp_server

    2.客户端代码

      1 import socket
      2 import os ,json
      3 import optparse
      4 import getpass
      5 import hashlib
      6 import sys 
      7 
      8 STATUS_CODE  = {
      9     250 : "Invalid cmd format, e.g: {'action':'get','filename':'test.py','size':344}",
     10     251 : "Invalid cmd ",
     11     252 : "Invalid auth data",
     12     253 : "Wrong username or password",
     13     254 : "Passed authentication",
     14     255 : "Filename doesn't provided",
     15 }
     16 
     17 class FTPClient(object):
     18     def __init__(self):
     19         parser = optparse.OptionParser()
     20         parser.add_option("-s","--server", dest="server", help="ftp server ip_addr")
     21         parser.add_option("-P","--port",type="int", dest="port", help="ftp server port")
     22         parser.add_option("-u","--username", dest="username", help="username")
     23         parser.add_option("-p","--password", dest="password", help="password")
     24         self.options , self.args = parser.parse_args()
     25         self.verify_args(self.options,self.args)
     26         self.make_connection()
     27 
     28     def make_connection(self):
     29         self.sock = socket.socket()
     30         self.sock.connect((self.options.server,self.options.port))
     31 
     32     def verify_args(self, options,args):
     33         '''校验参数合法型'''
     34         if options.username is not None and options.password is not  None:
     35             pass
     36         elif options.username is None and options.password is None:
     37             pass
     38         else:
     39             #options.username is None or options.password is None:
     40             exit("Err: username and password must be provided together..")
     41 
     42         if options.server and options.port:
     43             #print(options)
     44             if options.port >0 and options.port <65535:
     45                 return True
     46             else:
     47                 exit("Err:host port must in 0-65535")
     48 
     49     def authenticate(self):
     50         '''用户验证'''
     51         if self.options.username:
     52             print(self.options.username,self.options.password)
     53             return  self.get_auth_result(self.options.username, self.options.password)
     54         else:
     55             retry_count = 0
     56             while retry_count <3:
     57                 username = input("username:").strip()
     58                 password = input("password:").strip()
     59                 return self.get_auth_result(username,password)
     60 
     61     def get_auth_result(self,user,password):
     62         data = {'action':'auth',
     63                 'username':user,
     64                 'password':password}
     65 
     66         self.sock.send(json.dumps(data).encode())
     67         response = self.get_response()
     68         if response.get('status_code') == 254:
     69             print("Passed authentication!")
     70             self.user = user
     71             return True
     72         else:
     73             print(response.get("status_msg"))
     74 
     75     def get_response(self):
     76         '''得到服务器端回复结果'''
     77         data = self.sock.recv(1024)
     78         print("server res", data)
     79         data = json.loads(data.decode())
     80         return data
     81 
     82 
     83 
     84     def interactive(self):
     85         if self.authenticate():
     86             print("---start interactive iwth u...")
     87             while True:
     88                 choice = input("[%s]:"%self.user).strip()
     89                 if len(choice) == 0:continue
     90                 cmd_list = choice.split()
     91                 if hasattr(self,"_%s"%cmd_list[0]):
     92                     func = getattr(self,"_%s"%cmd_list[0])
     93                     func(cmd_list)
     94                 else:
     95                     print("Invalid cmd.")
     96     
     97     def __md5_required(self,cmd_list):
     98         '''检测命令是否需要进行MD5验证'''
     99         if '--md5' in cmd_list:
    100             return True
    101     def show_progress(self,total):
    102         received_size = 0 
    103         current_percent = 0 
    104         while received_size < total:
    105              if int((received_size / total) * 100 )   > current_percent :
    106                   print("#",end="",flush=True)
    107                   current_percent = int((received_size / total) * 100 )
    108              new_size = yield 
    109              received_size += new_size
    110     def _get(self,cmd_list):
    111         print("get--",cmd_list)
    112         if len(cmd_list) == 1:
    113             print("no filename follows...")
    114             return
    115         data_header = {
    116             'action':'get',
    117             'filename':cmd_list[1]
    118         }
    119         if self.__md5_required(cmd_list):
    120             data_header['md5'] = True
    121 
    122         self.sock.send(json.dumps(data_header).encode())
    123         response = self.get_response()
    124         print(response)
    125         if response["status_code"] ==257:#ready to receive
    126             self.sock.send(b'1')#send confirmation to server 
    127             base_filename = cmd_list[1].split('/')[-1]
    128             received_size = 0
    129             file_obj = open(base_filename,"wb")
    130             if self.__md5_required(cmd_list):
    131                 md5_obj = hashlib.md5()
    132                 progress = self.show_progress(response['file_size']) #generator 
    133                 progress.__next__()
    134                 while received_size < response['file_size']:
    135                     data = self.sock.recv(4096)
    136                     received_size += len(data)
    137                     try:
    138                       progress.send(len(data))
    139                     except StopIteration as e:
    140                       print("100%")
    141                     file_obj.write(data)
    142                     md5_obj.update(data)
    143                 else:
    144                     print("----->file rece done----")
    145                     file_obj.close()
    146                     md5_val = md5_obj.hexdigest()
    147                     md5_from_server = self.get_response()
    148                     if md5_from_server['status_code'] == 258:
    149                         if md5_from_server['md5'] == md5_val:
    150                             print("%s 文件一致性校验成功!" % base_filename)
    151                     #print(md5_val,md5_from_server)
    152 
    153             else:
    154                 progress = self.show_progress(response['file_size']) #generator 
    155                 progress.__next__()
    156 
    157                 while received_size < response['file_size']:
    158                     data = self.sock.recv(4096)
    159                     received_size += len(data)
    160                     file_obj.write(data)
    161                     try:
    162                       progress.send(len(data))
    163                     except StopIteration as e:
    164                       print("100%")
    165 
    166                 else:
    167                     print("----->file recv done----")
    168                     file_obj.close()
    169     def _put(self,cmd_list):
    170         print("put----",cmd_list)
    171         if len(cmd_list) == 1:
    172             print("no filename follows...")
    173             return
    174         data_header = {
    175             'action':'put',
    176             'filename':cmd_list[1]
    177         }
    178         self.sock.send(json.dumps(data_header).encode())
    179         #response = self.get_response()
    180         #print(response)
    181         print("client......")
    182         file_obj = open(cmd_list[1],"rb")
    183         file_size = os.stat(cmd_list[1]).st_size
    184         print(file_size)
    185         self.sock.send(str(file_size).encode())
    186         self.sock.recv(1024) #等待服务端确认
    187         progress = self.show_progress(file_size)  # generator
    188         progress.__next__()
    189         for i in file_obj:
    190             self.sock.send(i)
    191         else:
    192             try:
    193                 progress.send(int(file_size))
    194             except StopIteration as e:
    195                 print("100%")
    196             file_obj.close()
    197             print("send done...")
    198 if __name__ == "__main__":
    199     ftp = FTPClient()
    200     ftp.interactive() #交互
    ftp_client
  • 相关阅读:
    C#自定义控件之数字文本框
    C# 校验字符串是否为IP格式
    C# winform 解决加载闪烁,背景透明等问题
    SQL Server 数据类型
    C#自定义控件之下拉列表框
    C#将 byte[ ] 转换为对应的struct
    AFNetworking图片上传
    xfs删除oracle数据文件恢复
    揭秘String类型背后的故事——带你领略汇编语言魅力
    [批处理]截取for命令里面的变量%%i
  • 原文地址:https://www.cnblogs.com/liumj0305/p/6134956.html
Copyright © 2011-2022 走看看