day30 网络编程

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

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

同上,客户端:

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

粘包现象:

服务端:
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(b‘hello‘)
# time.sleep(3)
client.send(b‘world‘)

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

服务端
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()

客户端
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()

解决粘包问题:终结篇

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)

服务端:
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()

客户端:
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()

时间: 2024-11-07 10:53:37

day30 网络编程的相关文章

C#网络编程技术FastSocket实战项目演练

一.FastSocket课程介绍 .NET框架虽然微软提供了socket通信的类库,但是还有很多事情要自己处理,比如TCP协议需要处理分包.组包.粘包.维护连接列表等,UDP协议需要处理丢包.乱序,而且对于多连接并发,还要自己处理多线程等等.本期分享课程阿笨给大家带来的是来源于github开源Socket通信中间件:FastSocket,目的就是把大家从繁琐的网络编程技术中彻底地解放和释放出来. 阿笨只想安安静静的学习下网络编程技术Socket后,将学习的成果直接灵活的运用到自己的实际项目中去.

网络编程 -- RPC实现原理 -- RPC -- 迭代版本V1 -- 本地方法调用

网络编程 -- RPC实现原理 -- 目录 啦啦啦 V2--RPC -- 本地方法调用:不通过网络 入门 1. RPCObjectProxy rpcObjectProxy = new RPCObjectProxy(new LocalRPCClient()); : 绑定目标对象 2. IUserService userService = (IUserService) rpcObjectProxy.create(IUserService.class); :返回代理类 3. List<User> u

C#网络程序设计(1)网络编程常识与C#常用特性

    网络程序设计能够帮我们了解联网应用的底层通信原理!     (1)网络编程常识: 1)什么是网络编程 只有主要实现进程(线程)相互通信和基本的网络应用原理性(协议)功能的程序,才能算是真正的网络编程. 2)网络编程的层次 现实中的互联网是按照"TCP/IP分层协议栈"的体系结构构建的,因此程序员必须搞清楚自己要做的是哪个层次上的编程工作. TCP/IP协议体系的实现情况: 其中,网络接口层已经被大多数计算机生产厂家集成在了主板上,也就是经常所说的网卡(NIC).windows操

9. 网络编程:

网络编程: 端口: 物理端口: 逻辑端口:用于标识进程的逻辑地址,不同进程的标识:有效端口:0~65535,其中0~1024系统使用或保留端口. java 中ip对象:InetAddress. import java.net.*; class  IPDemo{ public static void main(String[] args) throws UnknownHostException{ //通过名称(ip字符串or主机名)来获取一个ip对象. InetAddress ip = InetA

物联网网络编程、Web编程综述

本文是基于嵌入式物联网研发工程师的视觉对网络编程和web编程进行阐述.对于专注J2EE后端服务开发的童鞋们来说,这篇文章可能稍显简单.但是网络编程和web编程对于绝大部分嵌入式物联网工程师来说是一块真空领域. 的确,物联网研发应该以团队协作分工的方式进行,所以有嵌入式设备端.网关.web前端.APP.后端开发等专属岗位.作为系统架构师,自然需要掌握各种岗位的关键技术.作为嵌入式工程师,掌握网络编程.web编程,能够极大地拓展自己的视野和架构思维,能够主动地对系统的各种协议和应用场景提出优化的见解

linux网络编程-(socket套接字编程UDP传输)

今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中,如果我们使用TCP传输,会造成传输速度较慢的情况,所以我们在进行文件传输的过程中,最好要使用UDP传输. 在其中,我们需要写两个程序,一个客户端,一个服务端,在一个终端中,先运行服务端,在运行客户端,在服务端和客户端都输入IP地址和端口号,注意服务端和客户端的端口号要相同,然后选择功能,在linux

UNIX网络编程卷1 回射客户程序 TCP客户程序设计范式

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 下面我会介绍同一个使用 TCP 协议的客户端程序的几个不同版本,分别是停等版本.select 加阻塞式 I/O 版本. 非阻塞式 I/O 版本.fork 版本.线程化版本.它们都由同一个 main 函数调用来实现同一个功能,即回射程序客户端. 它从标准输入读入一行文本,写到服务器上,读取服务器对该行的回射,并把回射行写到标准输出上. 其中,非阻塞式 I/O 版本是所有版本中执行速度最快的,

黑马程序员——网络编程篇

------- android培训.java培训.期待与您交流! ---------- 概述   1.网络模型        (1).OSI参考模型        (2).TCP/IP参考模型   2.网络通讯要素         (1).IP地址        (2).端口号         (3).传输协议    3.过程        1,找到对方IP. 2,数据要发送到对方指定的应用程序上.为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识. 为了方便称呼这个数据,叫做端口(逻

网络编程TCP/IP实现客户端与客户端聊天

一.TCP/IP协议 既然是网络编程,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输.这里就要使用到TCP/IP协议. TCP/IP协议(传输控制协议)由网络层的IP协议和传输层的TCP协议组成.IP层负责网络主机的定位,数据传输的路由,由IP地址可以唯一的确定Internet上的一台主机.TCP层负责面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象. 二.TCP与UDP TCP是一种面向连接的保证可靠传输的协议