zoukankan      html  css  js  c++  java
  • 第三十一天 udp通信和黏包

    1.默写一下上节课的tcp通讯程序:

      server端的程序;

    import socket
    sk=socket.socket() #创建一个socket对象
    sk.bind(('127.0.0.1',8090)) #给对象绑定一个ip和端口号
    sk.listen()  #进行监听
    conn,addr=sk.accept()#获取一个客户端的连接,这一步已经完成了三次握手,这一步会产生堵塞
    while True:
        ret=conn.recv(1024).decode('utf-8') #这一步也会产生堵塞
        if ret=='bye':
            break
        print(ret)
        info=input('请输入信息:')
        if ret=='bye':
            break
        conn.send(info.encode('utf-8'))
    conn.close()
    sk.close()
    View Code

      client端的程序:

    import socket
    sk=socket.socket()
    sk.connect(('127.0.0.1',8090))
    while True:
        info=input('请输入信息:')
        if info=='bye':
            sk.send(b'bye')
            break
        info='alex'+info
        sk.send(info.encode('utf-8'))
        ret=sk.recv(1024).decode('utf-8')
        print(ret)
        if ret=='bye':
            break
    sk.close()
    View Code

    2.如果有两个客户端和一个服务器进行通讯(通讯协议选用tcp协议,并且先启动client1,那么client2先发送信息,server可以接受到吗?)

      答:接受不到,当client启动之后,client1和server就建立了长连接,这个长连接是独自占用,只有当clent1断开之后才可以有其他的客户机于其交流

      server端程序:

    import socket
    sk=socket.socket()
    sk.connect(('127.0.0.1',8090))
    while True:
        info=input('请输入信息:')
        if info=='bye':
            sk.send(b'bye')
            break
        info='tigger'+info
        sk.send(info.encode('utf-8'))
        ret=sk.recv(1024).decode('utf-8')
        print(ret)
        if ret=='bye':
            break
    sk.close()
    View Code

      client1端程序:

    import socket
    sk=socket.socket()
    sk.connect(('127.0.0.1',8090))
    while True:
        info=input('请输入信息:')
        if info=='bye':
            sk.send(b'bye')
            break
        info='alex'+info
        sk.send(info.encode('utf-8'))
        ret=sk.recv(1024).decode('utf-8')
        print(ret)
        if ret=='bye':
            break
    sk.close()
    View Code

      client2端程序:

    import socket
    sk=socket.socket()
    sk.connect(('127.0.0.1',8090))
    while True:
        info=input('请输入信息:')
        if info=='bye':
            sk.send(b'bye')
            break
        info='tigger'+info
        sk.send(info.encode('utf-8'))
        ret=sk.recv(1024).decode('utf-8')
        print(ret)
        if ret=='bye':
            break
    sk.close()
    View Code

    3.使用udp协议进行通讯的程序:

      server端的程序:

    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)#创建对象,括号里面加上类型
    sk.bind(('127.0.0.1',8080))  #绑定ip和端口号
    while True:
        ret,addr=sk.recvfrom(1024)  #udp必须先要接受数据,为了获取返送端的地址
        print (addr)
        print(ret.decode('utf-8'))
        info =input('请输入一个信息:')
        info=info.encode('utf-8')
        sk.sendto(info,addr)  #数据的发送
    sk.close()
    View Code

      client端的程序:

    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    ip_port =('127.0.0.1',8080)
    while True:
        info=input('请输入信息:')
        info=('33[34m;%s:%s33[0m'%('alxe',info)).encode('utf-8')
        sk.sendto(info,ip_port)
        ret,addr=sk.recvfrom(1024)
        print(ret.decode('utf-8'))
    sk.close()
    View Code

      client2端的程序:

    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    ip_port =('127.0.0.1',8080)
    while True:
        info=input('请输入想要发的信息:')
        info=('33[32m;%s:%s33[0m'%('tigger',info)).encode('utf-8')
        sk.sendto(info,ip_port)
        ret,addr=sk.recvfrom(1024)
        print(ret.decode('utf-8'))
    sk.close()
    View Code

    4.subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。

    import subprocess
    res=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    ret=res.stdout.read()
    ret1=res.stderr.read().decode('gbk')
    print(ret)#输出数据时bytes类型
    ret=ret.decode('gbk')
    print('stdout',ret)
    print('stdeer',ret1)
    结果为
    b' xc7xfdxb6xafxc6xf7 D xd6xd0xb5xc4xbexedxcaxc7 DATA
     xbexedxb5xc4xd0xf2xc1xd0xbaxc5xcaxc7 5CB4-94EB
    
     D:\pythonxc1xb7xcfxb0xb3xccxd0xf2\xb5xdaxc8xfdxcaxaexd2xbbxccxec\demo4 xb5xc4xc4xbfxc2xbc
    
    2020/03/05  16:40    <DIR>          .
    2020/03/05  16:40    <DIR>          ..
    2020/03/05  16:15               304 client1.py
    2020/03/05  16:15               318 client2.py
    2020/03/05  16:40               269 practise.py
    2020/03/05  16:18               435 server.py
    2020/03/05  15:49                 0 __init__.py
                   5 xb8xf6xcexc4xbcxfe          1,326 xd7xd6xbdxda
                   2 xb8xf6xc4xbfxc2xbc 43,053,735,936 xbfxc9xd3xc3xd7xd6xbdxda
    '
    stdout  驱动器 D 中的卷是 DATA
     卷的序列号是 5CB4-94EB
    
     D:python练习程序第三十一天demo4 的目录
    
    2020/03/05  16:40    <DIR>          .
    2020/03/05  16:40    <DIR>          ..
    2020/03/05  16:15               304 client1.py
    2020/03/05  16:15               318 client2.py
    2020/03/05  16:40               269 practise.py
    2020/03/05  16:18               435 server.py
    2020/03/05  15:49                 0 __init__.py
                   5 个文件          1,326 字节
                   2 个目录 43,053,735,936 可用字节
    
    stdeer 
    View Code

    5.看下面这段程序我们可以发现什么问题:

      server端:

    import socket
    sk=socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.listen()
    conn,addr=sk.accept()
    
    while True:
        cmd=input('>>>')
        conn.send(cmd.encode('utf-8'))
        ret= conn.recv(1024).decode('utf-8')
        print(ret)
    conn.close()
    sk.close()
    View Code

      client端:

    import socket
    import subprocess
    sk=socket.socket()
    sk.connect(('127.0.0.1',8080))
    while True:
        cmd=sk.recv(1024).decode('gbk')
        ret=subprocess.Popen(cmd,shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        std_out='stdout:'+(ret.stdout.read()).decode('gbk')
        std_err='stderr'+(ret.stderr.read()).decode('gbk')
        sk.send(std_out.encode('utf-8'))
        sk.send(std_err.encode('utf-8'))
    sk.close()
    View Code

     

      通过结果我们不难看出发送的数据和接受的数据已经乱了,有时候出现接受过多的问题,有时候出现节后不玩的问题,这些问题我都都称之为黏包问题。

    6.对于udp来说如果出现数据量过大的情况又会有什么问题那:

    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)#创建对象,括号里面加上类型
    sk.bind(('127.0.0.1',8080))  #绑定ip和端口号
    while True:
        ret,addr=sk.recvfrom(1024)  #udp必须先要接受数据,为了获取返送端的地址
        print(ret.decode('utf-8'))
        info =input('请输入一个信息:')
        info=info.encode('gbk')
        sk.sendto(info,addr)  #数据的发送
    sk.close()
    View Code

      client

    import socket
    import subprocess
    sk=socket.socket(type=socket.SOCK_DGRAM)
    ip_port =('127.0.0.1',8080)
    while True:
        info=input('请输入信息:')
        info=info.encode('utf-8')
        sk.sendto(info,ip_port)
        ret,addr=sk.recvfrom(1024)
        ret=ret.decode('gbk')
        ret=subprocess.Popen(ret,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        std_out='std_out:'+(ret.stdout.read()).decode('gbk')
        std_err='std_err:'+(ret.stderr.read()).decode('gbk')
        sk.sendto(std_out.encode('utf-8'),ip_port)
        sk.sendto(std_err.encode('utf-8'),ip_port)
    sk.close()
    View Code

    从结果发现:我们会把多余的数据量丢弃。

    7.tcp'中

  • 相关阅读:
    如何修改 WordPress 的默认 Gravatar 头像
    解决wordpress部分博客文章页面无法显示的问题
    git删除本地所有的更改
    C++ char数组和string类简单使用总结
    c++ 中关于int,unsigned int , short的关系与应用
    CentOS下,mysql服务启动失败
    通过日志动态查看正在执行的mysql语句
    mysql 处理数据库中的重复行
    Linux cp复制
    在myeclipse中使用查找功能
  • 原文地址:https://www.cnblogs.com/ab461087603/p/12421416.html
Copyright © 2011-2022 走看看