PY3基础day8

静态方法

            与类无关,不能访问类里的任何属性和方法

类方法

           只能访问类变量

属性@property

           把一个方法变成静态属性,

           flight.status

            @status.setter

            flight.status = 3

           @status.delter

反射

  getattr(obj,str)

  setattr(obj,str,val)

  hasattr(obj,str)

 动态导入模块

#lib = __import__('lib.aa') #这是解释器自己内部用的;;
#lib.aa
import importlib
aa = importlib.import_module('lib.aa') #与上面的效果一样,官方建议用
print(aa.C().name)

__new__  ;; ;;   __call__

class Foo(obj):

     def __call__

                print"call"

  Foo()()#执行call方法

__metacless__用来定义这个类以怎样的形式被创建;

异常

try

  ......

except(ValueError,KeyError),e #IN2.7

except(ValueError,KeyError)as e :#3.X

except Exception as e: 放在异常处理的最后面;

else:#没发生异常,就执行

finally ,无论如何都执行

raise ValueErorr

断言assert()

assert type(obj.name) is int
print("dddddd")

socket 

        tcp/ip  send,recv

        udp

         family address

                   AF.INET  ipv4

                   AF.INET6

                   AF.UNIX local 

           socket protocol type

           socket .SOCK_STREAM  tcp/ip

            socket.SOCK_DGRAM   数据报式socket,for UDP

         服务端

        server = socket.socket(AF.INET,socket.STREAM)

         server.bind(localhost,9999)

         server.listen()

         conn,addr = server.accept() #阻塞

         while True:

                 print(“new conn ”,addr)

                data =  conn.recv(1024)  #8192  #recv 默认阻塞的

                                if not data:

                                            break #客户端已断开 ,conn.recv收到的都是空数据,

                                 print(data)

                                  conn.send(data.upper())

              client

                        client = socket.socket()

                         client.connect(serverip,9999)

                         client.send(data)

                         client.send(data)

                         client.recv(data)

ssh例子

socket_server_ssh.py

import os
import  socket
server = socket.socket()
server.bind(('localhost',9999))
server.listen()
while True:
    conn,addr = server.accept()
    print("new conn",addr)
    while True:
        print("等待新指令")
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        print("执行指令:",data)
        cmd_res = os.popen(data.decode()).read() #接受字符串,执行结果也字符串
        print("before send",len(cmd_res))
        if len(cmd_res) ==0:
            cmd_res = "cmd has no output..."
        conn.send(str(len(cmd_res.encode())).encode("utf-8"))    #先发大小给客户端
        conn.send(cmd_res.encode("utf-8"))
        print("send done")
server.close()
socket_server_client.py
import  socket
client = socket.socket()
client.connect(('localhost',9999))
while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0: continue
    client.send(cmd.encode("utf-8"))
    cmd_res_size = client.recv(1024) #接受命令结果的长度
    print("命令结果大小:",cmd_res_size)
    received_size = 0
    received_data = b''
    while received_size < int(cmd_res_size.decode()):
        data = client.recv(1024)
        received_size += len(data) #每次收到的有可能小于1024,所以必须用len判断
        print(data.decode())
        received_data += data
    else:
        print("cmd res receive done...",received_size)
        print(received_data.decode())
    #cmd_res = client.recv(1024)
    #print(cmd_res)
server.close()

socket  粘包

conn.send(str(len(cmd_res.encode())).encode("utf-8"))    #先发大小给客户端
#time.sleep(0.5)
client_ack = conn.recv(1024) #wait client to confirm
conn.send(cmd_res.encode("utf-8"))

 ftp server

1.读取文件名

2.检测文件是否存在

3.打开文件

4.检测文件大小

5.发送文件大小客户端

6.等客户端确认

7.开始边读边发数据

8.发送md5

socket 防粘包(linux系统)

socket_server_client.py

import hashlib

import  socket
client = socket.socket()
client.connect(('localhost',9999))
while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0: continue
    client.send(cmd.encode("utf-8"))
    cmd_res_size = client.recv(1024) #接受命令结果的长度
    print("文件大小:",cmd_res_size)
    client.send("准备接受了,loser可以发了".encode())
    received_size = 0
    if cmd.startswith("get"):
        client.send(cmd.encode())
        server_response = client.recv(1024)
        print("server response:",server_response)
        client.send(b"ready to recv file")
        file_total_size = int(server_response.decode())
        reversed_size = 0
        filename = cmd.split()[1]
        f = open(filename,"wb")
        m = hashlib.md5()

        while received_size < file_total_size:
            if file_total_size - received_size >= 1024: #要收不知一次
                size = 1024
            else: #最后一次,剩多少就收多少;
                size = file_total_size - received_size
                print("last receive",size)
            data = client.recv(size)
            received_size += len(data)
            m.update(data)
            f.write(data)
            print(file_total_size,received_size)
        else:
            new_file_md5 = m.hexdigest()
            print("file recv done",received_size,file_total_size)
            f.close()
        server_file_md5 = client.recv(1024)
        print("server file md5:",server_file_md5)
        print("client file md5:",new_file_md5)
client.close()
socket_server_ssh2.py
import hashlib
import os,time
import  socket
server = socket.socket()
server.bind(('localhost',9999))
server.listen()
while True:
    conn,addr = server.accept()
    print("new conn",addr)
    while True:
        print("等待新指令")
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
            '''
        print("执行指令:",data)
        cmd_res = os.popen(data.decode()).read() #接受字符串,执行结果也字符串
        print("before send",len(cmd_res))
        if len(cmd_res) ==0:
            cmd_res = "cmd has no output..."
        conn.send(str(len(cmd_res.encode())).encode("utf-8"))    #先发大小给客户端
        #time.sleep(0.5)
        client_ack = conn.recv(1024) #wait client to confirm
        conn.send(cmd_res.encode("utf-8"))'''
        cmd,filename = data.decode().split()
        print(filename)
        if os.path.isfile(filename):
            f = open(filename+".new","rb")
            m = haslib.md5()
            file_size = os.stat(filename).st_size
            conn.send(str(file_size).encode()) #send file size
            conn.recv(1024) #wait for ack()
            for line in f:
                m.update(line)
                conn.send(line)
            print("file md5",m.hexdigest())
            f.cloce()
            conn.send(m.hexdigest().encode()) #send() md5

        print("send done")
server.close()

6. SocketServer

The socketserver module simplifies the task of writing network servers.

socketserver一共有这么几种类型


1
class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)

This uses the Internet TCP protocol, which provides for continuous streams of data between the client and server. 


1
class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)

This uses datagrams, which are discrete packets of information that may arrive out of order or be lost while in transit. The parameters are the same as for TCPServer.


1
2
class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
class socketserver.UnixDatagramServer(server_address, RequestHandlerClass,bind_and_activate=True)

There are five classes in an inheritance diagram, four of which represent synchronous servers of four types:
+------------+
| BaseServer |
+------------+ | v +-----------+ +------------------+ | TCPServer |------->| UnixStreamServer | +-----------+ +------------------+ | v +-----------+ +--------------------+ | UDPServer |------->| UnixDatagramServer | +-----------+ +--------------------+

创建一个socketserver 至少分以下几步:

  1. First, you must create a request handler class by subclassing the BaseRequestHandlerclass and overriding its handle() method; this method will process incoming requests.   
  2. Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.
  3. Then call the handle_request() or serve_forever() method of the server object to process one or many requests.
  4. Finally, call server_close() to close the socket.

1.你必须自己创建一个请求类,并且这个类要继承BaseRequestHanderler,并且还要有重写父类里的Handle();

2.你必须实例化TCPServer,并且传递 server ip 和你上面创建的请求处理类 给这个TCPServer;

server.handle_request()  #只处理一个请求

server.serve_forever () #处理多一个请求,永远执行;

例子

#客户端
import socket
client = socket.socket() #声明socket类型,同时生成socket对象
client.connect(('localhost',9999))
while True:
    msg = input(">>:").strip()
    client.send(msg.encode("utf-8"))
    #client.send("我要自学".encode("utf-8"))
    data = client.recv(1024)
    print("recv:", data.decode())
client.close()
#服务端
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            self.data = self.request.recv(1024).strip()
            # self.request is the TCP socket connected to the client
            #self.data = self.request.recv(1024).strip()
            print("{} wrote:".format(self.client_address[0]))
            print(self.data)
            if not self.data: #客户端断了
                print(self.client_address,"断开了")
                break
            # just send back the same data, but upper-cased
            self.request.send(self.data.upper())

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
    server.serve_forever()
该服务端
#服务端
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                self.data = self.request.recv(1024).strip()
                # self.request is the TCP socket connected to the client
                # self.data = self.request.recv(1024).strip()
                print("{} wrote:".format(self.client_address[0]))
                print(self.data)
                '''
                if not self.data:  # 客户端断了
                    print(self.client_address, "断开了")
                    break
                '''
                # just send back the same data, but upper-cased
                self.request.send(self.data.upper())
            except ConnectionAbortedError as e:
                print("err",e)
                break
if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

           server.serve_forever()

多并发

换成下面这个,就可以多并发了,这样,客户端每连进一个来,服务器端就会分配一个新的线程来处理这个客户端的请求

server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) #多并发,多线程

#server = socketserver.ForkingTCPServer((HOST, PORT), MyTCPHandler)#多进程(linux

class socketserver.BaseServer(server_addressRequestHandlerClass) 主要有以下方法;





猜你喜欢

转载自blog.csdn.net/qq_37951246/article/details/80467334