主要内容:
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