第三十一天 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=('\033[34m;%s:%s\033[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=('\033[32m;%s:%s\033[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' \xc7\xfd\xb6\xaf\xc6\xf7 D \xd6\xd0\xb5\xc4\xbe\xed\xca\xc7 DATA\r\n \xbe\xed\xb5\xc4\xd0\xf2\xc1\xd0\xba\xc5\xca\xc7 5CB4-94EB\r\n\r\n D:\\python\xc1\xb7\xcf\xb0\xb3\xcc\xd0\xf2\\\xb5\xda\xc8\xfd\xca\xae\xd2\xbb\xcc\xec\\demo4 \xb5\xc4\xc4\xbf\xc2\xbc\r\n\r\n2020/03/05  16:40    <DIR>          .\r\n2020/03/05  16:40    <DIR>          ..\r\n2020/03/05  16:15               304 client1.py\r\n2020/03/05  16:15               318 client2.py\r\n2020/03/05  16:40               269 practise.py\r\n2020/03/05  16:18               435 server.py\r\n2020/03/05  15:49                 0 __init__.py\r\n               5 \xb8\xf6\xce\xc4\xbc\xfe          1,326 \xd7\xd6\xbd\xda\r\n               2 \xb8\xf6\xc4\xbf\xc2\xbc 43,053,735,936 \xbf\xc9\xd3\xc3\xd7\xd6\xbd\xda\r\n'
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'中

 

posted @ 2020-03-05 17:27  chown  阅读(194)  评论(0编辑  收藏  举报