• 10 Python编程:从入门到实践socket&socketserver 摩天居士


    socket基本语法

    server端配置

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 
     5 import socket
     6 
     7 server = socket.socket()
     8 server.bind(('localhost',6969))
     9 server.listen()
    10 
    11 print("我要开始等电话了")
    12 conn,addr = server.accept() #等连接进来
    13 print(conn,addr)
    14 
    15 print("电话来了")
    16 data = conn.recv(1024)
    17 print("recv:",data)
    18 conn.send(data.upper())
    19 
    20 server.close()
    View Code

    client端配置

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 
     5 import socket
     6 
     7 client = socket.socket()   #声明socket类型,同时生成socket连接对象
     8 client.connect(('localhost',6969))
     9 
    10 client.send(b"hello world!")
    11 data = client.recv(1024)
    12 print("rece:",data)
    13 
    14 client.close()
    View Code

    实例一:模拟ssh登录服务器,输入命令将命令结果返回客户端

    代码过程:

      1、server端监听客户端发来的命令

      2、服务端将命令通过os.popen方法将内容字符长度和命令内容返回给客户端

      3、客户端接收server端返回的命令字符长度,因为有可能一次长度超过1024,需要多次从缓冲区传输

    ssh server 端代码

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 
     5 import os
     6 import socket
     7 
     8 server = socket.socket()
     9 server.bind(('localhost',9999))
    10 server.listen()
    11 
    12 while True:
    13     conn,addr = server.accept()
    14     while True:
    15         data = conn.recv(1024)  #接收客户端发来的数据请求
    16         if not data: #如果客户端发来的数据请求内容为空,则终止这次循环
    17             break
    18         cmd_res = os.popen(data.decode()).read()
    19         if len(cmd_res) == 0:
    20             cmd_res = "cmd has no output...."
    21         conn.send(str(len(cmd_res.encode())).encode("UTF-8"))  #发送了一个返回结果的字符长度
    22         conn.send(cmd_res.encode("UTF-8"))  #并且将返回内容发送过去
    23     server.close()
    View Code

    ssh client端代码

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 
     5 import socket
     6 
     7 client = socket.socket()
     8 client.connect(('localhost',9999))
     9 
    10 while True:
    11     cmd = input(">>")
    12     if len(cmd) == 0:
    13         continue
    14     client.send(cmd.encode("UTF-8"))
    15     cmd_res_size = client.recv(1024)  #收到服务端返回的字符大小
    16     print("返回结果的字符大小为:",cmd_res_size)
    17     received_size = 0
    18     received_data = b''
    19     while received_size < int(cmd_res_size.decode()):   #如果命令结果小于发送过来字符总大小就进行循环
    20         cmd_res_msg = client.recv(1024)     #返回命令结果内容
    21         received_size += len(cmd_res_msg)   #收到的内容可能小于1024
    22         received_data += cmd_res_msg
    23     else:
    24         print("cmd res receive done....",received_size)
    25         print(received_data.decode())
    26 client.close()
    View Code

     实例二:通过socket实现文件发送

    代码过程:

    1. 读取文件名
    2. 检测文件是否存在
    3. 打开文件
    4. 检测文件大小
    5. 发送文件大小给客户端
    6. 等客户端确认
    7. 开始边读边发数据
    8. 发送md5校验

    ftp server端代码:

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 import os
     5 import socket
     6 import hashlib
     7 
     8 
     9 server = socket.socket()
    10 server.bind(('0.0.0.0',9099))
    11 server.listen()
    12 
    13 while True:
    14     conn,addr = server.accept()
    15     while True:
    16         data = conn.recv(1024)
    17         if not data:
    18             break
    19         print(data)
    20         cmd,filename = data.decode().split()
    21         if os.path.isfile(filename):
    22             f = open(filename,"rb")
    23             m = hashlib.md5()
    24             file_size = os.stat(filename).st_size
    25             conn.send(str(file_size).encode())
    26             conn.recv(1024)    #接收客户端防止粘包发送的内容
    27             for line in f:
    28                 m.update(line)
    29                 conn.send(line)
    30             #print("file md5",m.hexdigest())
    31             f.close()
    32             conn.send(m.hexdigest().encode())
    33     server.close()
    View Code

    ftp client端代码:

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 
     5 import socket
     6 import hashlib
     7 client = socket.socket()
     8 client.connect(('localhost',9099))
     9 
    10 while True:
    11     cmd = input(">>>").strip()
    12     if len(cmd) == 0:
    13         continue
    14     if cmd.startswith("get"):
    15         client.send(cmd.encode())
    16         server_response = client.recv(1024)    #接收server端判断的数据文件大小
    17         print(server_response)     #打印server端判断的数据文件大小
    18         client.send(b"ready to rece file")     # 目的是防止粘包
    19         file_total_size = int(server_response.decode())   #将server发送文件内容进行解码并转换成整数
    20         received_size = 0    #初始化变量文件大小为0
    21         filename = cmd.split()[1]    #获取客户端输出的文件名称
    22         f = open(filename + ".new","wb")      #将从server端读取的文件,写入到新文件
    23         m = hashlib.md5()
    24         while received_size < file_total_size:    #每次串1024字符
    25             if file_total_size - received_size > 1024:
    26                 size = 1024
    27             else:
    28                 size = file_total_size - received_size    #当不满1024个字符也一次发送过去
    29 
    30             data = client.recv(size)
    31             received_size += len(data)
    32             m.update(data)
    33             f.write(data)
    34             #print(file_total_size,received_size)
    35         else:
    36             new_file_md5 = m.hexdigest()
    37             print("file rece done",received_size,file_total_size)
    38             f.close()
    39         sever_file_md5 = client.recv(1024)
    40         print("server file md5:",sever_file_md5)
    41         print("client file md5:",new_file_md5)
    42 
    43 client.close()
    View Code

    执行结果如下:出现了以.new结尾的文件,并且md5校验码相同,说明两个文件内容相同

    socketserver级别操作

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 import socketserver
     5 
     6 
     7 class MyTCPHandler(socketserver.BaseRequestHandler):
     8     def handle(self):
     9         while True:
    10             try:
    11                 self.data = self.request.recv(1024).strip()
    12                 print("{} wrote:".format(self.client_address[0]))
    13                 print(self.data)
    14                 self.request.send(self.data.upper())
    15             except ConnectionError as e:
    16                 print("err",e)
    17                 break
    18 if __name__ == "__main__":
    19     HOST,PORT = "localhost",9999
    20     server = socketserver.TCPServer((HOST,PORT),MyTCPHandler)
    21     server.serve_forever()
    View Code
  • 相关阅读:
    java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
    Eclipse插件安装
    SQL 四种连接查询(内连接、左连接、右连接、全连接)
    数据库分页查询
    kafka shell命令
    you can't add a second 'create_time' expression specified as 'create_time : Document{{$lte=2020-07-31 00:00:00}}'.<br>Criteria already contains 'create_time : Document{{$gte=2020-07-01 00:00:00}}'
    nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block
    Nginx配置中不同请求匹配不同请求
    FastDFS 磁盘空间不足(tracker_query_storage fail,error no : 28,error info : No space left on device)
    Oracle临时表空间不足,ORA-01652:无法通过128(在表空间TEMP中)扩展temp段
  • 原文地址:https://www.cnblogs.com/weidongliu/p/16468917.html
Copyright © 2020-2023  润新知