第一阶段:Python开发基础 day32 网络编程之ssh通信和解决粘包问题

一、简单接收信息

server端:

import socket
soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind(('127.0.0.1',8081))
soc.listen(5)
print('等待客户端链接')
conn,addr = soc.accept()
while True:
    info = conn.recv(1024)
    print('客户端发送过来的信息:',info)
    conn.send(info.upper())

client端:

import socket
soc = socket.socket()
soc.connect(('127.0.0.1',8081))
while True:
    msg = input('请输入发送到服务端的信息:')
    if msg == 'q':
        break
    soc.send(msg.encode('utf8'))
    info = soc.recv(1024)
    print('服务端发送回来的消息:',info)

二、网络编程构建ssh通信

import socket
import subprocess

soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print('等待客户端链接')
soc.bind(('127.0.0.1',8081))

soc.listen(5)
conn, addr = soc.accept()
print('客户端已连接',addr)
while True:
    while True:
        cmd = conn.recv(1024) # 接收客户端传过来的cmd指令
        pipeline = subprocess.Popen(cmd.decode('utf8'),
                                    shell=True,
                                    stderr=subprocess.PIPE,
                                    stdout=subprocess.PIPE
                                    )
        stdout = pipeline.stdout.read()
        conn.send(stdout)

client端:

import socket
soc = socket.socket()

soc.connect(('127.0.0.1',8081))

while True:
    msg = input('input cmd:')
    soc.send(msg.encode('utf8'))

    data = soc.recv(1024)
    print(data.decode('gbk'))

三、解决粘包问题

server端:

import socket
import subprocess
import json
import struct
soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

soc.bind(('127.0.0.1',8081))

soc.listen(5)

while True:
    print('等待客户端链接')
    conn, addr = soc.accept()
    print('客户端已连接', addr)
    while True:
        try:
            cmd = conn.recv(1024) # 接收客户端传过来的cmd指令
            if len(cmd) == 0:
                break

            pipeline = subprocess.Popen(cmd.decode('utf8'),
                                        shell=True,
                                        stderr=subprocess.PIPE,
                                        stdout=subprocess.PIPE
                                        )

            msg = pipeline.stdout.read()  # 我们实际上要传的东西
            head = {'size':len(msg)}  # 自定义一个报头,用于存放我们实际要传的内容的长度
            print(head)
            # 为了该报头能传送,需要序列化并且转为bytes
            head_bytes = (json.dumps(head)).encode('utf8') #序列化并转成bytes,用于传输

            # 为了让客户端知道报头的长度,用struck将报头长度这个数字转成固定长度:4个字节
            head_bytes_len = struct.pack('i',len(head_bytes)) #这4个字节里只包含了一个数字,该数字是报头的长度
            # 处理完数据之后,可以开始向客户端发送数据了
            print(head_bytes_len)
            conn.send(head_bytes_len)  # 发送头长度
            conn.send(head_bytes)   # 发送头内容
            conn.send(msg)   # 发送了实际内容
        except Exception:
            break
    conn.close()

client端:

import socket
import struct
import json

soc = socket.socket()

soc.connect(('127.0.0.1',8081))

while True:
    msg = input('input cmd:')
    soc.send(msg.encode('utf8'))

    head_bytes_len = soc.recv(4)   # 拿到struct后的头长度

    head_len = struct.unpack('i',head_bytes_len)[0]  # 取出真正的头长度
    print(head_len)
    # 拿到真正的头部内容
    head_bytes = soc.recv(head_len)
    # 反序列化后取出头
    head = json.loads(head_bytes)

    # head头是一个字典,这样我们就可以取出真正要传输的内容的长度
    msg_len = head['size']
    msg = b''
    while msg_len > 1024:
        msg += soc.recv(1024)
        msg_len -= 1024
    else:
        msg += soc.recv(msg_len)
    print(str(msg,encoding='gbk'))
posted @ 2019-09-16 17:04  foreversun92  阅读(171)  评论(0编辑  收藏  举报