• Python--socket


    socket网络编程:socket、socketserver

    socket:{server,client}

    socket_server示例:

     1 import  socket # 导入模块
     2 server = socket.socket() #实例化一个server
     3 server.bind(('localhost', 6969)) # 绑定监听的地址和端口
     4 server.listen() # 开始监听
     5 while True: # 循环等待客户端的连接,当一个连接断开后,继续等待下个客户端的连接
     6     coon, addr = server.accept() # 等待客户端的连接,当有客户端连接时,conn,addr才有值
     7     while True: # 循环接收客户端的数据
     8         data = coon.recv(1024) #接收客户端的数据,接收数据大小为1K
     9         print("server recv:", data.decode()) #接收到的数据类型为b,需要decode
    10         if not data: # 如果无数据,则代表客户端断开
    11             print("client is lost...")
    12             break # 与客户端断开,等待下次客户端的连接
    13         coon.send(data.upper()) # 向客户端发送数据,注意将发送的数据encode(),此处data即为b类型,所以不需要
    14 server.close() # 实例关闭

    socket_client示例:

    import  socket #导入模块
    client = socket.socket() # 创建客户端实例
    client.connect(('localhost', 6969)) # 实例连接服务端地址及端口
    while True: # 循环接收用户输入并发送
        msg = input(">>:").strip() # 等待用户输入
        if len(msg.strip()) == 0: # 如果用户输入为空,则继续让用户输入
            continue
        client.send(msg.encode("utf-8")) # 将用户输入发送只server端
        data = client.recv(1024) # 接收server端发送的数据
        print("recv:", data.decode()) 
    client.close() # 客户端关闭

    应用:

    1、 使用socket实现类似ssh登录后执行命令的操作

    socket_ssh_server

     1 import socket,os,time # 导入模块
     2 server = socket.socket() # 实例化server
     3 server.bind(('localhost',9999)) # server绑定地址和端口
     4 server.listen() # 监听
     5 while True:
     6     conn, addr = server.accept() # 等待客户端的连接
     7     print("new conn:",addr)
     8     while True:
     9         print("等待新指令")
    10         data = conn.recv(1024) # 接收客户端的指令
    11         if not data:
    12             print("客户端已断开")
    13             break
    14         print("执行指令:",data)
    15         cmd_res = os.popen(data.decode()).read() #使用os.popen执行收到的指令,返回结果赋值给cmd_res
    16         print("before send",len(cmd_res)) # 输出命令的长度
    17         if len(cmd_res) ==0: # 如果指令结果长度为0,则没此命令
    18             cmd_res = "cmd has no output..." 
    19         conn.send( str(len(cmd_res.encode())).encode("utf-8"))     #先发大小给客户端
    20         conn.recv(1024) # 等待客户端确认,防止发送指令大小和发送结果出现粘包现象
    21         conn.send(cmd_res.encode("utf-8")) # 发送指令输出结果
    22         print("send done")
    23 server.close()

    socket_ssh_client

     1 import  socket # 导入模块
     2 client = socket.socket() # 实例化客户端
     3 client.connect(('localhost', 9999)) # 连接服务端
     4 while True: # 循环接收用户输入
     5     data = input(">>:").strip()
     6     if len(data) == 0:continue
     7     client.send(data.encode("utf-8")) # 发送指令
     8     result_data_size = client.recv(1024) # 接收执行返回结果的大小
     9     print(result_data_size.decode()) 
    10     client.send(b"please send cmd result")
    11     recv_data_size = 0
    12     recv_data = b""
    13     while recv_data_size < int(result_data_size.decode()): # 当指令结果大小大于1024时,循环接收指令结果
    14         recv_data_block = client.recv(1024)
    15         recv_data_size += len(recv_data_block)
    16         recv_data += recv_data_block
    17     else:
    18         print(recv_data_size)
    19         print(recv_data.decode())
    20 client.close()

    2、 使用socket实现文件发送并计算MD5值

    socket_file_server

     1 import socket, os, hashlib #导入模块
     2 server = socket.socket()
     3 server.bind(("localhost", 9999))
     4 server.listen()
     5 while True:
     6     conn, addr = server.accept()
     7     print("新连接:", addr)
     8     while True:
     9         print("等待指令")
    10         data = conn.recv(1024)
    11         if not data:
    12             print("客户端已断开")
    13             break
    14         filename = data.split()[1]
    15         print("文件名:", filename)
    16         m = hashlib.md5()
    17         if os.path.isfile(filename):
    18             file_size = os.stat(filename).st_size
    19             conn.send(str(file_size).encode())
    20             conn.recv(1024)
    21             print("等待接收端确认")
    22             f = open(filename, "rb")
    23             for line in f:
    24                 m.update(line)
    25                 conn.send(line)
    26             f.close()
    27             conn.send(m.hexdigest().encode())
    28         print("file send done")
    29 server.close()

    socket_file_client

     1 import  socket, hashlib
     2 client = socket.socket()
     3 client.connect(("localhost", 9999))
     4 while True:
     5     cmd = input(">>:").strip()
     6     if len(cmd) == 0:continue
     7     if cmd.startswith("get"):
     8         client.send(cmd.encode())
     9         filename = cmd.split()[1]
    10         res_filesize = client.recv(1024).decode()
    11         print("文件总大小是",res_filesize)
    12         client.send("please send".encode())
    13         m = hashlib.md5()
    14         recv_size = 0
    15         f = open(filename+"new","wb")
    16         while recv_size < int(res_filesize):
    17             if int(res_filesize) - recv_size > 1024: # 解决文件发送与MD5发送的粘包问题
    18                 size = 1024
    19             else:
    20                 size = int(res_filesize) - recv_size
    21             data = client.recv(size)
    22             recv_size += len(data)
    23             m.update(data)
    24             f.write(data)
    25         else:
    26             print("文件接收完毕,源文件大小%s,已接收文件大小%s" % (res_filesize,recv_size))
    27             old_file_md5 = client.recv(1024).decode()
    28         f.close()
    29         print("new file md5: ", m.hexdigest())
    30         print("old file md5: ", old_file_md5)
    31 client.close()

    3、 socketserver示例

    socketserver_server

     1 import  socketserver # 导入模块
     2 class MyTcpSocketServer(socketserver.BaseRequestHandler):  # 创建一个类,继承socketserver.BaseRequestHandler
     3     def handle(self): # 重写handle方法
     4         print(self.client_address)
     5         while True:
     6             try: #抓取客户端断开的异常
     7                 self.data = self.request.recv(1024).strip() # 接收客户端的数据
     8                 self.request.send(self.data.upper()) # 发送数据给客户端
     9             except ConnectionResetError as e:
    10                 print("Error:", e)
    11                 break
    12 
    13 if __name__ == "__main__":
    14     HOST, PORT = "localhost", 9889
    15     print(">>>>等待新连接>>>>")
    16     server = socketserver.ThreadingTCPServer((HOST, PORT), MyTcpSocketServer) #实例化,ThreadingTCPServer可以实现多用户同时交互
    17     server.serve_forever()  # 永久接收客户端的请求

    socketserver_client:直接使用socket模块即可

     1 import  socket
     2 client = socket.socket()
     3 client.connect(("localhost",9889))
     4 while True:
     5     data = input(">>:").strip()
     6     if len(data) == 0:continue
     7     client.send(data.encode())
     8     recv_data = client.recv(1024)
     9     print(recv_data)
    10 client.close()

    进阶

    使用面向对象实现客户端文件上传到服务器端

    socketserver_server

     1 import  socketserver,json,os # 导入模块
     2 
     3 class MyTcpServer(socketserver.BaseRequestHandler): # 创建socketserver类
     4 
     5     def put(self,*args):  # 接收文件函数
     6         file_dic = args[0]
     7         filename = file_dic["filename"]
     8         filesize = file_dic["size"]
     9         if os.path.isfile(filename):
    10             f = open(filename+".new","wb")
    11         else:
    12             f = open(filename,"wb")
    13         self.request.send(b"please send")
    14         recv_size = 0
    15         while recv_size < int(filesize):
    16             data = self.request.recv(1024)
    17             f.write(data)
    18             recv_size += len(data)
    19         else:
    20             print("接收完成")
    21 
    22     def handle(self): # 重写handle方法
    23         while True:
    24             try:
    25                 self.data = self.request.recv(1024).strip()
    26                 file_dic = json.loads(self.data.decode())
    27                 action = file_dic["action"]
    28                 if hasattr(self,action):  # 使用反射
    29                     func = getattr(self,action)
    30                     func(file_dic)
    31                 else:
    32                     print("no action:", action)
    33             except Exception as e:
    34                 print(e)
    35                 break
    36 
    37 if __name__ == "__main__":
    38     HOST,PORT = "localhost", 9999
    39     server = socketserver.ThreadingTCPServer((HOST,PORT), MyTcpServer)
    40     server.serve_forever()

    socketserver_client

     1 import  socket,os,json # 导入模块
     2 class MyFtpClient(object): # 定义客户端类
     3     def __init__(self):
     4         self.client = socket.socket()  # 客户端初始化
     5 
     6     def connect(self,ip,port):
     7         self.client.connect((ip,port)) # 连接服务端
     8 
     9     def interactive(self):
    10         while True: # 循环接收用户输入
    11             cmd = input(">>:").strip()
    12             if len(cmd)==0:continue
    13             cmd_split = cmd.split()
    14             action = cmd_split[0]
    15             if hasattr(self,action):  # 使用反射判断有无用户输入的指令,没有时返回help
    16                 func = getattr(self,action)
    17                 func(cmd_split)
    18             else:
    19                 self.help()
    20 
    21     def help(self):
    22         msg = '''
    23         ls
    24         pwd
    25         put filename
    26         cd ../..
    27         '''
    28         print(msg)
    29     def put(self,*args):  # 上传函数
    30         cmd_split = args[0]
    31         filename = cmd_split[1]
    32         if os.path.isfile(filename):  # 使用os模块判断文件是否存在
    33             filesize = os.stat(filename).st_size
    34             file_dic = {
    35                 "action": "put",
    36                 "filename": filename,
    37                 "size": filesize,
    38                 "overridden": True
    39             }
    40             self.client.send(json.dumps(file_dic).encode('utf-8'))
    41             self.client.recv(1024)
    42             f = open(filename,"rb")
    43             for line in f:
    44                 self.client.send(line)
    45             else:
    46                 print("send done")
    47         else:
    48             print(filename,"is nor exist")
    49 
    50 client = MyFtpClient() # 实例化客户端
    51 client.connect("localhost",9999) # 实例连接服务端
    52 client.interactive() # 实例调用用户交互函数
     
  • 相关阅读:
    20180915问题总结二
    20180917问题总结
    20190915问题总结
    常见问题整理目录
    电商中的库存管理实现-mysql与redis
    电商学习目录
    什么是SPU、SKU、SKC、ARPU
    C#趣味程序---三色球问题
    .NET开源的背后:是无奈,还是顺应潮流?
    mongoengine
  • 原文地址:https://www.cnblogs.com/sunnytomorrow/p/13435884.html
Copyright © 2020-2023  润新知