zoukankan      html  css  js  c++  java
  • python网络(2)_Tcp协议

    Socket

    Socket是套接字
    socket处于应用层与传输层之间,提供了一些简单的接口,避免与操作系统之间对接,省去了繁琐复杂的操作
    socket在python中属于一个模块,为我们提供了一些简单功能

    low比版本

    server服务端

    Android=socket.socket()
    Android.bind(("127.0.0.1",8866))#绑定服务器
    Android.listen(2)#监听
    conn,addr=Android.accept()#等待连接,这是个阻塞,拥有两个参数
    #conn是管道,addr客户端ip地址
    from_client_data =conn.recv(1024)#接收内容1024个字节
    #from_client_data是客户端的文字缓存
    print(F'客户端{addr}内容:{from_client_data}')
    string=input("请输入").strip().encode('utf-8')
    conn.send(string)
    conn.close()
    Android.close()
    

    client服务端

    Android=socket.socket()
    Android.connect(("127.0.0.1",8866))#绑定服务器
    string=input("请输入").strip().encode('utf-8')
    Android.send(string)
    from_client_data =Android.recv(1024)#接收内容1024个字节
    #from_client_data是客户端的文字缓存
    print(F'服务器内容:{from_client_data}')
    Android.close()
    
    

    非常厉害的版本

    服务端处理高级粘包

    #高级粘包处理
    
    Android=socket.socket()
    Android.bind(("127.0.0.1",8848))
    Android.listen(3)#允许有三个客户端加到半链接池子,超过会报错
    while 1:
        conn,arrd=Android.accept()
        print(f"连接成功一位{arrd}")
        while 1:
            try:
                from_client_data=conn.recv(1024)
                if from_client_data == b'0':
                    print(f"客户端{arrd}已经退出")
                    break
                obj = subprocess.Popen(from_client_data.decode("gbk"),
                                       shell=True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       )
                print(f'客户端{arrd}内容:{from_client_data.decode("gbk")}')
                result = obj.stdout.read() + obj.stderr.read()
                #1自定义报头
                head_dic = {
                    'file_name':"test1",
                    'md5':"656765678678",
                    'total_size':len(result),
                }
    
                #2json形式的报头
                head_dic_json=json.dumps(head_dic)
                #3bytes形式报头
                head_dic_json_bytes=head_dic_json.encode("gbk")
    
                #4获取bytes形式的报头总字节数
                len_head_dic_json_bytes=len(head_dic_json_bytes)
    
                #5将不固定的int总结字数固定长度4个字节
                four_head_bytes=struct.pack("i",len_head_dic_json_bytes)
                #6发送固定4长度的报头
                conn.send(four_head_bytes)
                #发送报头数据
                conn.send(head_dic_json_bytes)
                #发送总数据
                conn.send(result)
            except ConnectionResetError:
                print(f"客户端{arrd}已经退出")
                break
        conn.close()
    Android.close()
    

    客户端处理高级粘包

    phone=socket.socket()
    phone.connect(("127.0.0.1",8848))
    while 1:
        to_server_data=input("请输入").strip().encode("gbk")
        phone.send(to_server_data)
    
        if not to_server_data:
            print("输入内容不能为空")
            continue
        if to_server_data.upper() == "Q":
            print("客户端退出")
            break
        #1接收固定长度的四个字节
        head_bytes = phone.recv(4)
    
        #2获得bytes类型字典的总字节数
        len_head_dic_json_bytes = struct.unpack("i", head_bytes)[0]
    
        #3接收bytes形式的dic数据
        head_dic_json_bytes = phone.recv(len_head_dic_json_bytes)
    
        #4接收转换成json类型的dic
        head_dic_json=head_dic_json_bytes.decode('gbk')
    
        #5转换成字典形式的报头
        head_dic=json.loads(head_dic_json)
        tatal_data=b''
        while len(tatal_data) < head_dic["total_size"]:
            tatal_data += phone.recv(1024)
        print(tatal_data.decode("gbk"))
    phone.close()
    
    
  • 相关阅读:
    如何高效的学习技术
    面试连环炮系列(二十三): StringBuffer与StringBuild的区别
    面试连环炮系列(二十二):常用的设计模式有哪些
    算法天天练709:字符串转小写
    面试连环炮系列(二十一):你们的项目怎么使用kafka
    算法天天练771:查找字符串出现的次数
    初次进入职场如何工作与学习
    面试连环炮系列(二十):TCP的滑动窗口协议是什么
    算法天天练334:字符串翻转
    面试连环炮系列(十九):分布式锁的实现方案
  • 原文地址:https://www.cnblogs.com/SkyRabbit/p/11357141.html
Copyright © 2011-2022 走看看