基于tcp协议的套接字通信:远程执行命令

1.struct模块

#1、把整型数字转成bytes类型
#2、转成的bytes是固定长度的

import struct
import json

header_dic = {
    ‘total_size‘: 31222222222121,
    ‘md5‘: ‘123svsaef123sdfasdf‘,
    ‘filename‘: ‘a.txt‘
}

#序列化:内存中的数据结构----》转成一种中间格式(字符串)----》存到文件中
header_json=json.dumps(header_dic)
print(header_json,type(header_json))

#编码:编码后的结果为bytes类型
header_bytes=header_json.encode(‘utf-8‘)
header_size=len(header_bytes)
print(header_size)  # 81

#打包
obj=struct.pack(‘i‘,header_size)
print(obj,len(obj))  # b‘Q\x00\x00\x00‘ 4

#解包
obj2=struct.unpack(‘i‘,obj)
print(obj2)  # (81,)

打印结果:

{"total_size": 31222222222121, "md5": "123svsaef123sdfasdf", "filename": "a.txt"} <class ‘str‘>
81
b‘Q\x00\x00\x00‘ 4
(81,)

result

2.通讯整个流程:

‘‘‘
流程:
    服务端:制作报头,把报头信息丢到报头字典里,字典序列化得到json字符串,encode得到bytes
          ---->发报头长度(struct.pack打成4个bytes)--->发送报头---->发真实数据

    客户端:先接收4个bytes:struct.unpack解包报头长度--->接收报头-->
             解析报头:decode得到字符串,反序列化得到报头--->根据报头内的信息,收取真实的数据

‘‘‘

3.具体代码如下:

服务端:

from socket import *
import subprocess
import struct
import json

server=socket(AF_INET,SOCK_STREAM)
server.bind((‘127.0.0.1‘,8080))
server.listen(5)               #监听客户端的链接请求

while True:
    conn,client_addr=server.accept() #(连接对象,客户端的ip和端口)  conn:tcp三次握手的一个产物,可以用来收发消息
    print(client_addr)     #此处client_addr的作用是可以知道哪个客户端建的链接,和通讯无关
    while True:
        try:
            cmd=conn.recv(1024)   #cmd为bytes类型,
            obj=subprocess.Popen(cmd.decode(‘utf-8‘),
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE
                                 )
            stdout=obj.stdout.read()  #系统命令,解码需要gbk
            stderr=obj.stderr.read()

            # 1、制作报头
            header_dic={
                ‘total_size‘:len(stdout) + len(stderr),
                ‘md5‘:‘123svsaef123sdfasdf‘,
                ‘filename‘:‘a.txt‘
            }
            header_json = json.dumps(header_dic)         #json序列化报头
            header_bytes = header_json.encode(‘utf-8‘)   #字符串类型---->bytes类型,发送

            # 2、先发送报头的长度
            header_size=len(header_bytes)
            conn.send(struct.pack(‘i‘,header_size))

            # 3、发送报头
            conn.send(header_bytes)

            # 4、发送真实的数据
            conn.send(stdout)     #send只能发bytes类型
            conn.send(stderr)
        except ConnectionResetError:
            break
    conn.close()
server.close()

客户端:

from socket import *
import struct
import json           

client=socket(AF_INET,SOCK_STREAM)
client.connect((‘127.0.0.1‘,8080))
# print(client)

while True:
    cmd=input(‘>>>: ‘).strip()
    if not cmd:continue
    client.send(cmd.encode(‘utf-8‘))     #把命令结果发给服务器
    #1、先收报头的长度根据报头内的信息,收取真实的数据
    header_size=struct.unpack(‘i‘,client.recv(4))[0]    #bytes类型,想拿到报头长度要对bytes进行解出

    #2、接收报头
    header_bytes=client.recv(header_size)   #对应服务端的发送报头

    #3、解析报头
    header_json=header_bytes.decode(‘utf-8‘)    #bytes类型---->字符串类型
    header_dic=json.loads(header_json)         #反序列化拿到报头
    print(header_dic)

    total_size=header_dic[ ‘total_size‘]
    # print(total_size) #1025
    #4、接收数据

    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()

原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/11783058.html

时间: 2024-10-23 22:20:40

基于tcp协议的套接字通信:远程执行命令的相关文章

什么是 socket?简述基于 tcp 协议的套接字通信流程?

Socket的英文原义是"孔"或"插座".通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄, 可以用来实现不同虚拟机或不同计算机之间的通信. 在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务. 基于tcp 协议的套接字通信流程: 1). 服务器先用 socket 函数来建立一个套接字,用这个套接字完成通信的监听. 2). 用 bind

python基础之socket编程-------基于tcp的套接字实现远程执行命令的操作

远程实现cmd功能: import socket import subprocess phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bind(("127.0.0.1",8080)) phone.listen(5) print("starting....") while True: conn,addr=phone.accept() while True: try: date=conn.recv

网络编程(四)——基于udp协议的套接字socket、socketserver模块的使用

基于udp协议的套接字.socketserver模块 一.UDP协议(数据报协议) 1.何为udp协议 不可靠传输,"报头"部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包. 以太网头 ip头                      udp头                            数据                                            tcp协议(流式协议) 2.udp协议的特点 (1)传输数据以数据报的形

Python网络编程02/基于TCP协议的socket简单的通信

目录 Python网络编程02/基于TCP协议的socket简单的通信 1.昨日内容回顾 2.socket 2.1 socket套接字 2.2 基于TCP协议的socket简单通信 Python网络编程02/基于TCP协议的socket简单的通信 1.昨日内容回顾 1.单播:单独联系某一个人 2.广播:给所有人发送消息(群发) 3.比特流:bit就是0101跟水流一样的源源不断的发送01010101 4.以太网协议:将数据进行分组:一组称之为一帧,数据报 head|data head:18字节:

网络编程[第二篇]基于udp协议的套接字编程

udp协议下的套接字编程 一.udp是无链接的    不可靠的 而上篇的tcp协议是可靠的,会有反馈信息来确认信息交换的完成与否 基于udp协议写成的服务端与客户端,各司其职,不管对方是否接收到信息,只需自己发送了即可 二.客户端 import socket #买手机 -- 套接字家族 | 端口协议 phone = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #服务端地址 ip_port = ('127.0.0.1',8001) #实现多次发送

基于TCP协议的socket套接字编程

基于TCP协议的socket套接字编程 一.什么是Socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议. 所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的. [ 注意:也有

粘包产生的原因 socket 基于tcp实现远程执行命令(解决粘包)low

# 粘包产生的原因 # 粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的. # 基于tcp协议的套接字会有粘包现象,而基于udp协议的套接字不会产生粘包现象 # tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住:而udp是基于数据报的,即使你输入的是空内容,那也不是空消息,udp协议会帮你封装上消息头(ip+端口的方式),这样就有了消息办界 # 两种情况下会发生粘包 # 1.发送端需要等缓冲区满才发送

一起talk C栗子吧(第一百五十六回:C语言实例--基于AF_UNIX域的流套接字通信)

各位看官们,大家好,上一回中咱们说的获取socket通信地址的例子,这一回咱们说的例子是:基于AF_UNIX域的流套接字通信 .闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在前面章回中介绍了套接字的通信过程以及套接字的的细节,总感觉还缺少些什么,一时还真是想不起来.这好比我们有了食谱也有了食材,那么我们就可以做一道美味的佳肴了.啊!有了.一提到美味的佳肴,灵感就来了.我们缺少的是对套接字的综合演练,也就是把前面章回中知识串在一起,然后举一个综合使用套接字知识进行套接字通信的例

TCP下的套接字编程

1.什么是套接字 应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据.为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口.区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址.使用的传输层协议(TCP或UDP)和使用的端口号.Socket原意是"插座".通过将这3个参数结合起来,