zoukankan      html  css  js  c++  java
  • socket加入循环和粘包问题

    socket

    socket加入通信循环

    客户端

    import socket
    
    soc = socket.socket()
    soc.connect(('127.0.0.1', 8080))
    
    while True:
        inp = input('请输入要发送的信息>>>')
        soc.send(inp.encode('utf-8'))
    

    服务端

    import socket
    
    soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    soc.bind(('127.0.0.1', 8080))
    soc.listen(5)
    conn, addr = soc.accept()
    
    while True:
        try:
            data = conn.recv(1024)
            print(data)
        except Exception:
            conn.close()
            break
    
    soc.close()
    

    socket加入连接循环

    客户端

    import socket
    
    soc = socket.socket()
    soc.connect(('127.0.0.1', 8080))
    
    while True:
        inp = input('请输入要发送的消息>>>')
    	soc.send(inp.encode('utf-8'))
    

    服务端

    import socket
    
    soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    soc.bind(('127.0.0.1', 8080))
    soc.listen(5)
    
    while True:
        print('等待客户端连接...')
        conn, addr = soc.accept()
        print(f'客户端{addr}已连接上了')
        
        while True:
            try:
                data = conn.recv(1024)
                print(data)
            except Exception:
                break
                
    	conn.close()
        
    soc.close()
    

    ssh

    ssh是远程执行命令

    subprocess是执行系统命令的模块

    import subprocess
    
    # 执行系统dir命令,把执行的正确结果放到管道中
    obj = subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)
    # 拿到正确结果的管道,读出里面的内容
    content = obj.stdout.read()
    # 因为windows是用gbk编码的,所以要用gbk解码
    print(str(content,encoding='gbk'))
    

    粘包问题

    粘包现象

    客户端

    import socket
    
    soc = socket.socket()
    soc.connect(('127.0.0.1', 8080))
    
    while True:
        inp = input('请输入要发送的消息>>>')
        soc.send(b'a')
        soc.send(b'b')
        soc.send(b'c')
    

    服务端

    import socket
    
    soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    soc.bind(('127.0.0.1', 8080))
    soc.listen(5)
    
    while True:
        print('等待客户端连接...')
        conn, addr = soc.accept()
        print(f'客户端{addr}已连接上了')
        
        while True:
            try:
                data1 = conn.recv(1024)
                print(data1)
                data2 = conn.recv(1024)
                print(data2)
                data3 = conn,recv(1024)
                print(data3)
            except Exception:
                break
                
    	conn.close()
        
    soc.close()
    

    客户端发送a、b、c的消息时,服务端有时候会接收到好几个值,而不是单个的a、b、c,这个就是粘包问题。

    注意:只有TCP有粘包现象,UDP永远不会粘包

    因为TCP协议是基于数据流的,所以收发的消息是不能为空的;但是UDP协议是基于数据报的,即使发送了空内容,UDP协议也会封装上消息头,因此也不会是空内容。

    解决粘包问题的方法

    给我们要发送的消息加上自定义长度报头,报头中包含我们要发送消息的长度,接收消息的时候,先从读取固定长度的报头,然后再读取真实的长度。

    客户端

    import json
    import socket
    import struct
    
    client = socket.socket()
    client.connect(('127.0.0.1', 8080))
    while True:
        content = input('开始接收信息>>>')
        head_len = struct.unpack('i', client.recv(4))[0]
        dic = json.loads(client.recv(head_len))
        size_len = dic['size']
        name = dic['name']
        count = 0
        data = b''
        with open(name, 'wb') as fw:
            while count < size_len:
                if size_len < 1024:
                    data_temp = client.recv(size_len)
                else:
                    if size_len - count >= 1024:
                        data_temp = client.recv(1024)
                    else:
                        data_temp = client.recv(size_len - count)
                        
    			data = data_temp
                count += len(data_temp)
                
    		f.write(data)
            
    	print('接收完成')
        
    client.close()
    

    服务端

    import os
    import json
    import socket
    import struct
    
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    
    while True:
        conn, addr = server.accept()
        
        while True:
            dic = {'size': os.path.getsize('run.py'), 'name': 'new_run.py'}
            dic_bytes = bytes(json.dumps(dic), 'utf-8')
            dic_bytes_len = len(dic)
            head = struct.pack('i', dic_bytes_len)
            
            conn.send(head)
            conn.send(dic_bytes)
            with open('run.py', 'rb') as fr:
                for line in fr:
                    conn.send(line)
                    
    	conn.close()
        
    server.close()
    
  • 相关阅读:
    跃迁方法论 Continuous practice
    EPI online zoom session 面试算法基础知识直播分享
    台州 OJ 2648 小希的迷宫
    洛谷 P1074 靶形数独
    洛谷 P1433 DP 状态压缩
    台州 OJ FatMouse and Cheese 深搜 记忆化搜索
    台州 OJ 2676 Tree of Tree 树状 DP
    台州 OJ 2537 Charlie's Change 多重背包 二进制优化 路径记录
    台州 OJ 2378 Tug of War
    台州 OJ 2850 Key Task BFS
  • 原文地址:https://www.cnblogs.com/yunluo/p/11568288.html
Copyright © 2011-2022 走看看