zoukankan      html  css  js  c++  java
  • 远程-粘包现象

    远程执行命令

    远程执行命令 : 在客户端输入一个命令,通过网络传输给服务器,服务器后端运行此命令得到结果,将结果通过网络传输返回给客户端

    
    
    subprocess模块
    import subprocess
    obj = subprocess.Popen('dir',         #命令
                           shell = True,
                           stdout = subprocess.PIPE,
                           stderr = subprocess.PIPE
                           )
    print(obj.stdout.read().decode('gbk'))    #正确命令
    print(obj.stderr.read().decode('gbk'))    #错误命令
    
    #shell :命令解释器,相当于调用cmd执行指定的命令
    #stdout:正确结果丢到一个管道当中
    #stderr:错了丢到另一个管道当中
    #windows操作系统的默认编码是gbk
    # 服务端:
    import socket
    import subprocess
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('127.0.0.1',10086))
    server.listen(5)
    while 1:
        conn, addr = server.accept()  # 等待客户端连接
        while 1:
            try:
                cmd = conn.recv(1024).decode('utf-8')  # 最大接受的字节数
                # 接受命令
                obj = subprocess.Popen(
                    cmd,
                    shell=True,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                )
                right_msg = obj.stdout.read()
                error_msg = obj.stderr.read()
                # 通过subprocess或者执行命令的结果
                print(right_msg,error_msg)
                conn.send(right_msg + error_msg)  # gbk 的bytes
                # 将结果发送给客户端
            except Exception:
                break
        conn.close()
    server.close()
    # 客户端
    import socket
    
    client = socket.socket()
    client.connect(('127.0.0.1',10086))
    while 1 :
        cmd = input('>>>').strip()
        client.send(cmd.encode('utf-8'))
        result = client.recv(1024)
        print(result.decode('gbk'))
    client.close()

    粘包现象

    粘包现象1:

    客户端发送一段数据,recv时只收了一小部分,客户端下次再接收的时候还是从缓冲区拿上次遗留的数据,产生粘包

    客户端 ---send()命令---> 客户端缓冲区 ---网络---> 服务端缓冲区 ---recv----> 服务端
    服务端会执行客户端发送的命令,例如得到1254个字节

    服务端 ---send()---> 服务端缓冲区 ---网络---> 客户端缓冲区 ---recv----> 客户端
    客户端只接收1024个字节,还会剩下230个字节留在客户端缓冲区

    等到下一次再次输入命令时,客户端最后接收的只有230个字节,没有本次执行命令的结果

    原因:只要客户端将数据send除去,就会立马进入recv状态 会直接打印在客户端缓冲区的230个字节,而不会等到本次的命令走完整个流程

    粘包现象2:

    如果连续快速的发送几次少量的数据,那么服务端会一次接受完毕.

    # 服务端:
    
    import socket
    
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('127.0.0.1',10086))
    server.listen(5)
    conn,addr = server.accept()    
    data1 = conn.recv(1024)    
    print(data1)
    data2 = conn.recv(1024)   
    print(data2)
    conn.send(b'taibai')
    conn.close()
    server.close()
    # 客户端:
    
    import socket
    
    client = socket.socket()
    client.connect(('127.0.0.1',10086))
    client.send(b'hello')
    client.send(b'world')
    from_server_data = client.recv(1024)
    print(from_server_data)
    client.close()
    运行结果:
    b'helloworld'
  • 相关阅读:
    进程池,线程池,协程,gevent模块,协程实现单线程服务端与多线程客户端通信,IO模型
    线程相关 GIL queue event 死锁与递归锁 信号量l
    生产者消费者模型 线程相关
    进程的开启方式 进程的join方法 进程间的内存隔离 其他相关方法 守护进程 互斥锁
    udp协议 及相关 利用tcp上传文件 socketserver服务
    socket套接字 tcp协议下的粘包处理
    常用模块的完善 random shutil shevle 三流 logging
    day 29 元类
    Django入门
    MySQL多表查询
  • 原文地址:https://www.cnblogs.com/sandy-123/p/10413547.html
Copyright © 2011-2022 走看看