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

Socket传输简单的信息以及粘包问题的解决

时间:2018-05-26 13:26:23      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:std   connect   ssh   shell   cep   AC   传输   解析   byte   

  一、简单的socket程序——传输简短文字:

技术分享图片
# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
import socket

whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
whw_client.connect((127.0.0.1,9001))
while 1:
    cmd = input(>>>:).strip()
    if not cmd:
        continue
    whw_client.send(cmd.encode(utf-8))
    recv_data = whw_client.recv(1024)
    data = recv_data.decode(utf-8)
    print(server data:,data)
client
技术分享图片
# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
import socket

whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
whw_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
whw_server.bind((127.0.0.1,9001))
whw_server.listen(5)
print(listening......)
conn,addr = whw_server.accept()
#通信循环
while 1:
    try:
        recv_data = conn.recv(1024)
        data = recv_data.decode(utf-8)
        print(client data:,data)
        conn.send(data.swapcase().encode(utf-8))
    except ConnectionResetError:
        break
conn.close()
server

  演示如下:

技术分享图片

二、模拟SSH命令——解决粘包问题版:

  关于粘包问题的解决方案:

  在服务器端,由于解析出来的命令结果非常多,所以我们在发送结果之前需要先给客户端发送一个“报文”,这个报文保存着具体的命令结果的信息——其中关键的信息就是结果的长度,客户端只有知道这个结果的长度后,才能制定相应的接收规则:

技术分享图片
# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
import socket
import json
import struct

whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
whw_client.connect((127.0.0.1,9000))
while 1:
    try:
        cmd = input(>>>:).strip()
        if not cmd:
            continue
        #发命令
        whw_client.send(cmd.encode(utf-8))
        #1.收报头长度
        obj = whw_client.recv(10)
        #注意structunpack出来的[0]值为长度信息
        header_size = struct.unpack(i,obj)[0]
        #2.收报头——根据报头长度来收
        header_bytes = whw_client.recv(header_size)
        #3.从报头中解析出‘total_size‘
        header_json = header_bytes.decode(utf-8)
        header_dic = json.loads(header_json)
        total_size = header_dic[total_size]
        #根据total_size开始接收真实的数据
        recv_size = 0
        recv_data = b‘‘
        while recv_size < total_size:
            res = whw_client.recv(1024)
            recv_data += res
            recv_size += len(res)
        print(命令结果:\n,recv_data.decode(gbk))
    except Exception as e:
        whw_client.close()
client
技术分享图片
# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
import socket
import subprocess
import json
import struct

whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
whw_server.bind((127.0.0.1,9000))
whw_server.listen(5)
print(Listening......)
conn,addr = whw_server.accept()
while 1:
    try:
        #收命令
        cmd_recv = conn.recv(1024).decode(utf-8)
        #解析命令
        obj = subprocess.Popen(cmd_recv,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        stdout = obj.stdout.read()
        stderr = obj.stderr.read()
        #将命令返回给客户端
        #1.制作固定报头——注意报头里面要包含数据的总长度!
        header_dic = {filename:whw,total_size:len(stdout)+len(stderr)}
        header_json = json.dumps(header_dic)
        header_bytes = header_json.encode(utf-8)
        #2.发送报头长度——struct:把数字打成固定长度
        conn.send(struct.pack(i,len(header_bytes)))
        #3.发送报头
        conn.send(header_bytes)
        #4.发送真实数据
        conn.send(stdout)
        conn.send(stderr)
    except ConnectionResetError:
        break

conn.close()
server

  演示如下:

 技术分享图片

 

Socket传输简单的信息以及粘包问题的解决

标签:std   connect   ssh   shell   cep   AC   传输   解析   byte   

原文地址:https://www.cnblogs.com/paulwhw/p/9092629.html

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