day27 service and client

subprocess module

1. The terminal can help you through the operating system command code execution

And returns the result of the terminal 2. Run

Note: stdout stderr must be in front

import subprocess

cmd=input('cmd>>>:')

obj=subprocess.Popen(
    cmd,shell=True,
    stdout=subprocess.PIPE,#返回正确结果参数
    stderr=subprocess.PIPE#返回错误结果参数
)

result=obj.stdout.read()+obj.stderr.read()
print(result.decode('gbk'))

Stick package problem

Data sent from the server for the first time, received a single client can not be accurately completed. The next data transmitted on the primary data stick together.

1. The need to accept the other party can not predict the size of the data length

2. multiple successive data transmit small amounts of data, and the time interval is shorter disposable package sent

TCP protocol features:

tcp is a streaming protocol will send several successive small amount of data, and the time interval is short data package sent disposable

Stick package to solve the problem

struct module

It may be a very long length data, compressed to a fixed mark length (data header).

We must first define the header, sending a header, and then send real data

That is the description of want to send a file, and want to send the file

'''
-struct模块:
    是一个可以将很长的数据的长度,压缩成固定的长度的一个标记(数据报头)
'''
import struct
#打包压缩
# i模式,会将数据长度压缩成4个bytes
str1='nihaoyanihaoyanihaoya'

# 报头

headers=struct.pack('i', len(str1))

data_len=struct.unpack('i',headers)
print(data_len)#(21,)
print(data_len[0])#21

Stick package to solve the problem

#服务端
import socket
import subprocess
import struct

server=socket.socket()

server.bind(('127.0.0.1',9527))

server.listen(5)

while True:
    conn,addr=server.accept()
    while True:
        try:

            cmd=conn.recv(1024).decode('utf-8')
            if cmd=='q':
                break

            if len(cmd)==0:
                continue

            print(cmd)
            # 执行cmd命令
            obj=subprocess.Popen(cmd,shell=True,
                                 stderr=subprocess.PIPE,
                                 stdout=subprocess.PIPE,)
            #接受终端返回的数据
            result=obj.stdout.read()+obj.stderr.read()
            #打包压缩,获取报头
            headers=struct.pack('i',len(result))
            #发送报头
            conn.send(headers)
            #发送真实数据
            conn.send(result)
        except Exception as e:
            print(e)
            break
    conn.close()
#客户端
import socket
import struct

client=socket.socket()

client.connect(('127.0.0.1',9527))

while True:
    cmd=input('>>>:')

    client.send(cmd.encode('utf-8'))

    if cmd=='q':
        break
    #获取数据报头
    headers=client.recv(4)
    #解包,获取真实数据长度
    data_len=struct.unpack('i',headers)
    #获取真实数据
    data=client.recv(data_len[0])

    print(data.decode('gbk'))
client.close()

Upload dictionary

#服务端
import socket
import json
import struct

server=socket.socket()
server.bind(('127.0.0.1',8888))
server.listen(5)

while True:
    conn,addr=server.accept()
    while True:
        try:
            headers=conn.recv(4)
            data_len=struct.unpack('i',headers)[0]
            bytes_data=conn.recv(data_len)
            #先解码再反序列化
            back_dic=json.loads(bytes_data.decode('utf-8'))
            print(back_dic)
        except Exception as e:
            print(e)
            break
    conn.close()
#客户端
import socket
import struct
import json
import time

cilent=socket.socket()
cilent.connect(('127.0.0.1',8888))
while True:
    send_dic={
        'file_name':'nick真实写真集.avi',
        'file_size':1000000
    }
    #json序列化,并转换成bytes类型数据
    json_data=json.dumps(send_dic)
    bytes_data=json_data.encode('utf-8')

    # 先做报头
    headers=struct.pack('i',len(bytes_data))
    cilent.send(headers)
    cilent.send(bytes_data)
    time.sleep(3)

Upload large files

#服务端
import socket
import json
import struct

server=socket.socket()

server.bind(('127.0.0.1',8888))

server.listen(3)
while True:
    conn,addr=server.accept()
    while True:
        try:
            #获取字典报头
            headers=conn.recv(4)
            #解包获取字典数据长度
            data_len=struct.unpack('i',headers)[0]
            #获取字典真实数据
            bytes_dic=conn.recv(data_len)
            #樊=反序列得到字典
            back_dic=json.loads(bytes_dic.decode('utf-8'))
            print(back_dic)
            #得到字典的文件名以及视频文件按的大小
            file_name=back_dic['file_name']
            file_size=back_dic['file_size']

            init_data=0
            #打开文件 准备写入
            with open(file_name,'wb') as f:
                while init_data<file_size:
                    data=conn.recv(1024)
                    f.write(data)
                    init_data+=len(data)
                    num=init_data/file_size
                    print(f'已接受{num:.2%}')
                print(f'{file_name}接收完毕')
        except Exception as e:
            print(e)
            break
    conn.close()
#客户端
import socket
import struct
import json

client=socket.socket()
client.connect(('127.0.0.1',8888))

#打开一个视频文件,获取视频数据大小
with open(r'C:\Users\zqf\Desktop\新建文件夹\八重樱_桃源恋歌_1080p.mp4','rb') as f:
    movie_bytes=f.read()

# 为视频文件组织一个字典,字典内有视频文件按的名称和大小
send_dic={
    'file_name':'八重樱-桃源恋歌',
    'file_size':len(movie_bytes)
}

# 先打包字典 发送报头,再发送字典真实数据
json_data=json.dumps(send_dic)
bytes_data=json_data.encode('utf-8')
headers=struct.pack('i',len(bytes_data))

# 发送报头
client.send(headers)
#发送字典真实数据
client.send(bytes_data)

# 发送视频真实数据
init_data=0
with open(r'C:\Users\zqf\Desktop\新建文件夹\八重樱_桃源恋歌_1080p.mp4','rb') as f:
    while init_data<len(movie_bytes):
        send_data=f.read(1024)
        client.send(send_data)
        num=init_data/len(movie_bytes)
        print(f'数据传输{num:.2%}')
        init_data+=len(send_data)

UDP

It is a transport protocol

1. The need to establish a two-way pipeline

2. The package will not stick

3. The client sends data to the server without waiting for the server to accept successful return

4. loss of data content, data is insecure

-TCP: like to call

-UDP: like texting

#服务端
import socket
#.SOCK_DGRAM代表了UDP
server=socket.socket(type=socket.SOCK_DGRAM)
#绑定了ip+port
server.bind(('127.0.0.1',8888))

msg,addr=server.recvfrom(1024)
msg1,addr1=server.recvfrom(1024)
msg2,addr2=server.recvfrom(1024)

print(msg,msg1,msg2)
#客户端
import socket

client=socket.socket(type=socket.SOCK_DGRAM)

server_ip_port=(('127.0.0.1',8888))

client.sendto(b'hello',server_ip_port)
client.sendto(b'hello',server_ip_port)
client.sendto(b'hello',server_ip_port)
client.sendto(b'hello',server_ip_port)
client.sendto(b'hello',server_ip_port)

QQ chat room

#服务端
import socket

server=socket.socket(type=socket.SOCK_DGRAM)

server.bind(('127.0.0.1',8888))

while True:
    msg,addr=server.recvfrom(1024)
    print(addr)
    print(msg.decode('utf-8'))

    send_msg=input("客户端向服务端发消息").encode('utf-8')
    server.sendto(send_msg,addr)
#客户端
import socket

client=socket.socket(type=socket.SOCK_DGRAM)

server_ip_port=('127.0.0.1',8888)
while True:
    send_msg=input('客户端向服务端发消息').encode('utf-8')
    client.sendto(send_msg,server_ip_port)

    msg=client.recv(1024)
    print(msg.decode('utf-8'))

SocketServer

python built-in module, the socket can be simplified socket server code

- simplify TCP / UDP Service Code

- must create a class

#服务端
import socketserver

#必须定义类
#TCP:必须继承BaseRequestHandler类
class MyTcpServer(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.client_address)
        while True:
            try:
                #request.recv==conn.recv
                data=self.request.recv(1024).decode('utf-8')
                send_msg=data.upper()
                self.request.send(send_msg.encode('utf-8'))

            except Exception as e:
                print(e)
                break

if __name__ == '__main__':
    #socketserver.TCPServer只能一个服务
    # server=socketserver.TCPServer(
    #     ('127.0.0.1',8888),MyTcpServer
    # )
    #
    #socketserver.ThreadingTCPServer 多个服务
    server=socketserver.ThreadingTCPServer(
        ('127.0.0.1', 8888), MyTcpServer
    )
    server.serve_forever()
#客户端
import socket
client=socket.socket()

client.connect(
    ('127.0.0.1',8888)
)
while True:
    send_msg=input('客户端:')
    client.send(send_msg.encode('utf-8'))
    back_msg=client.recv(1024)
    print(back_msg.decode('utf-8'))

Guess you like

Origin www.cnblogs.com/zqfzqf/p/11700684.html