day5 课堂笔记 网络编程

今日内容大纲

  1. 解决粘包法案高大上版
  2. 基于UDP协议的socket
  3. socketserver

1. 解决粘包方案高大上版

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JQHV5OM9-1605164264849)(day05\day05 课堂笔记.assets\image-20201112083815914.png)]

  • 服务端

    import socket
    import subprocess
    import struct
    import json
    server = socket.socket()
    server.bind(('127.0.0.1', 8848))
    server.listen(5)
    while 1:
    	conn, addr = server.accept() # 阻塞, 等待客户机连接
    	while 1:
    		try:
    			from_client_cmd = conn.recv(1024)
    			if from_client_cmd.upper() == b'Q':
    				break
    			obj = suprocess.Popen(from_client_cmd.decode('utf-8'),
    			shell = True,
    			stdout = subprocess.PIPE,
    			stderr = subprocess.PIPE,
                                     )
                result = (obj.stdout.read() + obj.stderr.reak()).decode('gbk').encode('utf-8')
                print(f'文件的总字节个数{len(result)}') # int 类型
                #制作头部字典
                head_dic = {
                    'file_name':'文件名',
                    'md5':'a54g78a787ga6gdahr68t78fd7h6s7',
                    'file_size':len(result)
                }
                # 将head_dic转化成字符串
                head_dic_json = json.dumps(head_dic)
                # 将head_dic_json转化成bytes类型
                head_dic_json_bytes = head_dic_json.encode('utf-8')
                # 获得head_dic_json_bytes总字节个数
                head_dic_json_bytes_len = len(head_dic_json_bytes)
                # 将head_dic_json_bytes_len转化成固定长度bytes类型
                four_bytes = struct.pack('i', head_dic_json_bytes_len) # 固定4个字节(struct作用)
                conn.send(four_bytes)
                conn.send(head_dic_json_bytes)
                conn.send(result)
            except ConnectionResetError:
                break
            # 关闭通道
        conn.close()
    server.close()
                
    
  • 客户端

    import socket
    import struct
    import json
    client = socket.socket()
    client.connect(('127.0.0.1', 8848)) # 链接服务端
    while 1:
        to_server_data = input('命令>>>')
        client.send(to_server_data.encode('utf-8'))
        if to_server_data.upper() == 'Q':
            break
        # 获取固定头部
        four_bytes = client.recv(4)
        head_dic_json_bytes_len = struct.unpack('i', four_bytes)[0]
        # 接收head_dic_json_bytes数据
        head_dic_json_bytes = client.recv(head_dic_json_bytes_len)
        # 解码成json
        head_dic_json = head_dic_json_bytes.decode('utf-8')
        # 解码成head_dic
        head_dic = json.loads(head_dic_json)
        total = b''
        while len(total) < head_dic['file_size']:
            total += client.recv(1024)
        print(f'结果:{total.decode("utf-8")}')
    client.close()
    

2. 基于UDP协议的socket

  • 服务端

    import socket
    # 基于网络的UDP的socket对象
    server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server.bind(('127.0.0.1', 9000))
    while 1:
        msg, addr = server.recvfrom(1024)
        print(f'来自{addr}客户的消息:{msg.decode("utf-8")}')
        to_client_data = input('>>')
        server.sendto(to_cliend_data.encode('utf-8'), addr)
    server.close
    
  • 客户端

    import socket
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    while 1:
        to_server_data = input('>>>')
        client.sendto(to_server_data.encode('utf-8'), ('127.0.0.1', 9000))
        from_server_data, addr = client.ercvfrom(1024)
        print(f'来自服务端{addr}的消息:{from_server_data.decode("utf-8")}')
    

3.socketserver

  • 代码

    import socketserver
    
    
    class MyServer(socketserver.BaseRequestHandler):  # 类名随便定义,但是必须继承socketserver.BaseRequestHandler此类
    
        def handle(self):  # 必须以此命名
            while 1:
                # self.request == conn 管道对象
                from_client_data = self.request.recv(1024)
                print(f'客户端的数据:{from_client_data.decode("utf-8")}')
                to_client_data = input('》》》')
                self.request.send(to_client_data.encode('utf-8'))
    
    
    if __name__ == '__main__':
        ip_port = ('127.0.0.1', 8848)
        server = socketserver.ThreadingTCPServer(ip_port, MyServer)
        # 对 socketserver.ThreadingTCPServer 类实例化对象,将ip地址,端口号以及自己定义的类名传入,并返回一个对象
        server.serve_forever()  # 开启服务端
        
        
    import socket
    import time
    
    client = socket.socket()  # 创建客户端对象
    
    client.connect(('127.0.0.1', 8848))  # 链接服务端
    while 1:
        to_server_data = input('请输入:>>>>')
        client.send(('玮哥说:' + to_server_data).encode('utf-8'))
        if to_server_data.upper() == 'Q':
            break
        from_server_data = client.recv(1024)  # 阻塞
        print(f"服务端回复:{from_server_data.decode('utf-8')}")
    
    client.close()
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EOMhztBf-1605164264853)(day05\day05 课堂笔记.assets\image-20201112105520476.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vK0iDlgA-1605164264859)(day05\day05 课堂笔记.assets\image-20201112105700120.png)]

找下面类中的int类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SVRjrGg8-1605164264860)(day05\day05 课堂笔记.assets\image-20201112105808786.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vs9T4tDV-1605164264861)(day05\day05 课堂笔记.assets\image-20201112110037381.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8cVQtAwA-1605164264862)(day05\day05 课堂笔记.assets\image-20201112110446662.png)]

先研究BaseServer类中的init

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z2TOL7sq-1605164264864)(day05\day05 课堂笔记.assets\image-20201112110800573.png)]

研究server_bind方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HUtbrlIr-1605164264865)(day05\day05 课堂笔记.assets\image-20201112110908000.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1QcQyagb-1605164264867)(day05\day05 课堂笔记.assets\image-20201112111118690.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i7HeDzU2-1605164264868)(day05\day05 课堂笔记.assets\image-20201112111236914.png)]

存中...(img-z2TOL7sq-1605164264864)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值