zoukankan      html  css  js  c++  java
  • 31 黏包现象

    主要内容:

    1. 执行命令 :

      在python中去调用操作系统的命令  引入新的模块  : subprocess

    import subprocess
    r = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    # subprocess.Popen(cmd,shell=True,subprocess.stdout,subprocess.stderr)
    # cmd : 代表系统命令
    # shell = True   代表这条命令是 系统命令,告诉操作系统,将cmd当成系统命令去执行
    # stdout   是执行完系统命令之后,用于保存结果的一个管道
    # stderr   是执行完系统命令之后,用于保存错误结果的一个管道
    print(r.stdout.read().decode('gbk'))
    print(r.stderr.read().decode('gbk'))
    

      用subprocess实现,客户端发送要执行的命令, 服务器执行,执行完结果返回客户端, 客户端拿到结果后呈现在用户眼前.

      服务器端的代码:

    import socket
    import subprocess
    sk = socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.listen()
    conn, addr = sk.accept()
    ret = conn.recv(1024).decode('utf-8')
    r = subprocess.Popen(ret, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout = r.stdout.read()
    stderr = r.stderr.read()
    if stdout:
        conn.send(stdout)
    else:
        conn.send(stderr)
    conn.close()
    sk.close()
    

      客户端的代码:

    import socket
    import subprocess
    sk = socket.socket()
    sk.connect(('127.0.0.1',8080))
    cmd = input('请用户输入要执行的操作系统的命令:')
    sk.send(cmd.encode('utf-8'))
    ret = sk.recv(1024).decode('gbk')    # 操作系统中的编码为gbk
    print(ret)
    sk.close()
    

    2. 黏包问题 :在发送端发送数据,接收端不知道应该如何去接收,造成的一种数据紊乱的现象.

      a :tcp出现黏包的代码:

        服务器端:

    import socket
    sk = socket.socket()
    sk.bind(('127.0.0.1',8888))
    sk.listen()
    conn,addr = sk.accept()
    conn.send(b'hello')
    conn.send(b'world')
    conn.close()
    sk.close()
    

      客户端:

    import socket
    sk = socket.socket()
    sk.connect_ex(('127.0.0.1',8888))
    msg1 = sk.recv(1024)
    print('msg1:',msg1)
    msg2 = sk.recv(1024)
    print('msg2:',msg2)
    sk.close()
    

      b : udp不会出现黏包现象:代码:

        服务器端:

    import socket
    sk = socket.socket(type=socket.SOCK_DGRAM)
    sk.bind(('127.0.0.1',8888))
    while 1:
        msg1 = sk.recvfrom(5)
        print('msg1:',msg1)
    
        msg2 = sk.recvfrom(1024)
        print('msg2:',msg2)
    sk.close()
    

      客户端:

    import socket
    sk = socket.socket(type=socket.SOCK_DGRAM)
    while 1:
        sk.sendto(b'hello',('127.0.0.1',8888))
        sk.sendto(b'world',('127.0.0.1',8888))
    sk.close()
    

        c :  tcp协议中,出现两种黏包现象 : 合包机制和拆包机制

      合包机制的过程:

        过程一 : 发送方引起的黏包是由于tcp协议本身引起的, tcp为了提高自己的效率,发送方往往要收集足够多的数据后才发送一个tcp段.

        过程二 : 若连续几次send的数据都比较小,通常tcp会把这些数据打包合成一个tcp后一次性发送过去,这样接收方就收到了黏包数据.

      拆包机制的过程:

        在发送端,因为受到网卡的mtu限制,会将大的超过mtu限制的数据,进行拆分,拆分成多个小的数据,进行传输,当传输到目标主机的操作系统时,会          重新将多个小的数据合成原来的数据.

        当发送端缓冲区的长度大于网卡的MTU时,tcp会将这次发送的数据拆成几个数据包发送出去。
        MTU是Maximum Transmission Unit的缩写。意思是网络上传送的最大数据包。MTU的单位是字节。 大部分网络设备的MTU都是1500。如果        本机的MTU比网关的MTU大,大的数据包就会被拆开来传送,这样会产生很多数据包碎片,增加丢包率,降低网络速度。

    3 .  使用udp协议发送数据, 一次收发数据究竟多少合适:

      1): udp不会发生黏包 , udp协议本层对一次收发数据大小的限制是:

        65535 - ip包头(20) - udp包头(8) = 65507

      2): 站在数据链路层, 因为网卡的mtu一般被限制在了1500,所以对于数据链路层来说,收发数据的大小的限制 :

        1500 - ip包头(20) - udp包头(8) = 1472

  • 相关阅读:
    980不同路径III
    输入函数
    IDEA更新maven依赖包
    join()函数
    方差偏差困境
    np.bincount()函数
    72编辑距离
    741摘樱桃
    523连续的子数组和
    1306跳跃游戏III
  • 原文地址:https://www.cnblogs.com/gyh412724/p/9475532.html
Copyright © 2011-2022 走看看