码迷,mamicode.com
首页 > 其他好文 > 详细

day30 网络编程

时间:2017-11-28 18:40:49      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:stderr   day   class   gif   world   ide   系统   ota   错误   

 

 

subprocess模块:

这个模块的作用就是跟系统操作相关的调用系统命令,类似于os模块,比os更加强大。
它本身自带一个管道,这个管道就类似于临时存储数据的的容器,把中间值存入里面,

然后当需要的时候就从中取出。取出的时候里面有多少就可以取出多少,同一份内容不会重复取出,
意思就是只有一份内容,你反复执行取出操做,它只能给你倒出一次,倒完了就没有了。

然后管道里面的执行命令分为错误命令和正确命令,分别存储,用不同的关键字操作。

技术分享图片
import subprocess

obj=subprocess.Popen(dir,shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )
# print(‘========hahahahahah‘)

# print(obj.stdout.read().decode(‘gbk‘))
# print(obj.stdout.read().decode(‘gbk‘))
# print(obj.stdout.read().decode(‘gbk‘))
# print(obj.stdout.read().decode(‘gbk‘))
# print(obj.stdout.read().decode(‘gbk‘))

print(obj.stderr.read().decode("gbk"))
View Code

 

跟subprocess模块相关操作:

服务端

技术分享图片
import subprocess
from socket import *
server=socket(AF_INET,SOCK_STREAM)
server.bind((127.0.0.1,8081))
# print(server)
server.listen(5)
while True:
    conn,addr=server.accept()
    # print(conn)
    print(addr)
    while True:
        try:
            cmd=conn.recv(8096)
            if not cmd:break #针对linux

            #执行命令
            cmd=cmd.decode(utf-8)
            #调用模块,执行命令,并且收集命令的执行结果,而不是打印
            obj = subprocess.Popen(cmd, shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   )
            stdout=obj.stdout.read()
            stderr=obj.stderr.read()
            #发送命令的结果
            conn.send(stdout+stderr)
        except ConnectionResetError:
            break
    conn.close()

server.close()
View Code

同上,客户端:

技术分享图片
from socket import *

client=socket(AF_INET,SOCK_STREAM)
client.connect((127.0.0.1,8081))

while True:
    cmd=input(>>: ).strip()
    if not cmd:continue
    client.send(cmd.encode(utf-8))

    data=client.recv(1024)
    print(data.decode(gbk))

client.close()
View Code

 

 

粘包现象:

技术分享图片
服务端:
import time
from socket import *
server=socket(AF_INET,SOCK_STREAM)
server.bind((127.0.0.1,8082))

server.listen(5)

conn,addr=server.accept()

# res1=conn.recv(1)
# print(res1)
# res2=conn.recv(1)
# res3=conn.recv(1)
# res4=conn.recv(1)
# res5=conn.recv(1)
# print(res2)
# print(res3)
# print(res4)
# print(res5)



# res1=conn.recv(1)
# print(res1)
# time.sleep(4)
# res2=conn.recv(1024)
# print(res2)


print(conn.recv(1111111111111111111111111111111111111111111))
print(conn.recv(5))




#===============================================
客户端
import time
from socket import *

client=socket(AF_INET,SOCK_STREAM)
client.connect((127.0.0.1,8082))

client.send(bhello)
# time.sleep(3)
client.send(bworld)
View Code

 

 

struct模块:

它就是把数字转成固定长度的bytes类型。

struct.error: ‘i‘ format requires -2147483648 <= number <= 2147483647 #这个是范围

技术分享图片

 

技术分享图片
import struct

#帮我们把数字转成固定长度的bytes类型
res=struct.pack(i,123123)
print(res,len(res))

res1=struct.unpack(i,res)
print(res1[0])



# 有兴趣可以把上图里的都试一遍,这里只是试了一种方法,i
View Code
技术分享图片
服务端
import subprocess
import struct
from socket import *
server=socket(AF_INET,SOCK_STREAM)
server.bind((127.0.0.1,8084))
# print(server)
server.listen(5)
while True:
    conn,addr=server.accept()
    # print(conn)
    print(addr)
    while True:
        try:
            cmd=conn.recv(8096)
            if not cmd:break #针对linux

            #执行命令
            cmd=cmd.decode(utf-8)
            #调用模块,执行命令,并且收集命令的执行结果,而不是打印
            obj = subprocess.Popen(cmd, shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   )
            stdout=obj.stdout.read()
            stderr=obj.stderr.read()
            #第一步:制作报头:
            total_size=len(stdout)+len(stderr)

            header=struct.pack(i,total_size)  # 这里是打成一个包,包里面是一个数字的固定长度
            #第二步:先发报头(固定长度)
            conn.send(header)

            #第三步:发送命令的结果
            conn.send(stdout)
            conn.send(stderr)
        except ConnectionResetError:
            break
    conn.close()

server.close()
View Code
技术分享图片
客户端
import struct
from socket import *

client=socket(AF_INET,SOCK_STREAM)
client.connect((127.0.0.1,8084))

while True:
    cmd=input(>>: ).strip()
    if not cmd:continue
    client.send(cmd.encode(utf-8))

    #第一步:收到报头
    header=client.recv(4)
    total_size=struct.unpack(i,header)[0]  # 这里是把接收到的数据解包,得到它原本的样子,(类似于压缩解压缩)

    #第二步:收完整真实的数据
    recv_size=0
    res=b‘‘
    while recv_size < total_size:
        recv_data=client.recv(1024)
        res+=recv_data
        recv_size+=len(recv_data)
    print(res.decode(gbk))

client.close()
View Code

 

 

解决粘包问题:终结篇

技术分享图片
import struct

#帮我们把数字转成固定长度的bytes类型
# res=struct.pack(‘i‘,123123)
# print(res,len(res))
#
# res1=struct.unpack(‘i‘,res)
# print(res1[0])


# res=struct.pack(‘q‘,121231231233123)
# print(res,len(res))



import json
header_dic={
    md5:asdfasdfasdfasdfasdfasdf,
    total_size:1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111,
    filename:a.txt
 }

header_json=json.dumps(header_dic)

header_bytes=header_json.encode(utf-8)
print(len(header_bytes))
header_size=struct.pack(i,len(header_bytes))


# conn.send(header_size) ##recv(4)
# conn.send(header_bytes)  #recv(报头长度)
# conn.send(stdout)
# conn.send(stderr)
View Code
技术分享图片
服务端:
import subprocess
import struct
import json
from socket import *
server=socket(AF_INET,SOCK_STREAM)
server.bind((127.0.0.1,8086))
# print(server)
server.listen(5)
while True:
    conn,addr=server.accept()
    # print(conn)
    print(addr)
    while True:
        try:
            cmd=conn.recv(8096)
            if not cmd:break #针对linux

            #执行命令
            cmd=cmd.decode(utf-8)
            #调用模块,执行命令,并且收集命令的执行结果,而不是打印
            obj = subprocess.Popen(cmd, shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   )
            stdout=obj.stdout.read()
            stderr=obj.stderr.read()


            # 1:先制作报头,报头里放:数据大小, md5, 文件
            header_dic = {
                total_size:len(stdout)+len(stderr),
                md5: xxxxxxxxxxxxxxxxxxx,
                filename: xxxxx,
                xxxxx:123123
            }
            header_json = json.dumps(header_dic)
            header_bytes = header_json.encode(utf-8)
            header_size = struct.pack(i, len(header_bytes))

            # 2: 先发报头的长度
            conn.send(header_size)

            # 3:先发报头
            conn.send(header_bytes)

            # 4:再发送真实数据
            conn.send(stdout)
            conn.send(stderr)
        except ConnectionResetError:
            break
    conn.close()

server.close()
View Code
技术分享图片
客户端:
import struct
import json
from socket import *

client=socket(AF_INET,SOCK_STREAM)
client.connect((127.0.0.1,8086))

while True:
    cmd=input(>>: ).strip()
    if not cmd:continue
    client.send(cmd.encode(utf-8))

    # 1:先收报头长度
    obj = client.recv(4)
    header_size = struct.unpack(i, obj)[0]

    # 2:先收报头,解出报头内容
    header_bytes = client.recv(header_size)
    header_json = header_bytes.decode(utf-8)
    header_dic = json.loads(header_json)

    print(header_dic)
    total_size = header_dic[total_size]

    # 3:循环收完整数据
    recv_size=0
    res=b‘‘
    while recv_size < total_size:
        recv_data=client.recv(1024)
        res+=recv_data
        recv_size+=len(recv_data)
    print(res.decode(gbk))

client.close()
View Code

 

day30 网络编程

标签:stderr   day   class   gif   world   ide   系统   ota   错误   

原文地址:http://www.cnblogs.com/2012-dream/p/7911314.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!