python-- socket 粘包、实现 ssh

简介: python-- socket 粘包、实现 ssh

粘包


只有tcp协议才会发送粘包,udp不会发生。发送端发送数据,接收端不知道应该如何去接收,造成的一种数据混乱的现象

import subprocess
r = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# subprocess.Popen(cmd,shell=True,subprocess.stdout,subprocess.stderr)
# cmd : 代表系统命令
# shell = True   代表这条命令是 系统命令,告诉操作系统,将cmd当成系统命令去执行
# stdout   是执行完系统命令之后,用于保存结果的一个管道
# stderr   是执行完系统命令之后,用于保存错误结果的一个管道
stdout = r.stdout.read().decode('gbk')
stderr = r.stderr.read().decode('gbk')
print('正确的返回结果:',stdout)
print('错误的返回结果:',stderr)
print('错误的返回结果:',stderr)

客户端发送要执行命令

服务器执行,执行完将结果返回给客户端

客户端拿到结果呈现到用户眼前

服务端

import socket
import subprocess
sk = socket.socket()
sk.bind(('127.0.0.1', 8080))
sk.listen()
conn, addr = sk.accept()
while 1:
    cmd = conn.recv(1024).decode('utf-8')
    r = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout = r.stdout.read()
    stderr = r.stderr.read()
    if stderr:
        conn.send(stderr)
    else:
        conn.send(stdout)
conn.close()
sk.close()

客户端

import socket
sk = socket.socket()
sk.connect_ex(('127.0.0.1', 8080))
while 1:
    cmd = input('请输入一个命令>>>')
    sk.send(cmd.encode('utf-8'))
    result = sk.recv(102)
    result = result.decode('gbk')
    print(result)
sk.close()


socket 实现 ssh


a = '邹'
print(len(a))  # 1
print(len(a.encode()))  # 3  转换为bytes一个汉字三个字符

客户端

import socket
client = socket.socket()
client.connect(('localhost', 9999))
while True:
    msg = input(">>:").strip()
    if len(msg) == 0:  # 输入的为空
        continue
    client.send(msg.encode("utf-8"))
    data = client.recv(1024)
    print("recv:", data.decode())
client.close()

服务端

import socket, os
server = socket.socket()
server.bind(('localhost', 9999))
server.listen()
while True:
    conn, addr = server.accept()
    print('new conn', addr)
    while True:
        data = conn.recv(1024)
        if not data:
            print('客户端已断开')
            break
        print('执行指令:', data)
        cmd_res = os.popen(data.decode()).read()  # 执行输入的命令,decode转换为字符串
        if len(cmd_res) == 0:
            cmd_res = 'cmd has no out'
        conn.send(cmd_res.encode('utf-8'))  # 转为utf-8发过去

当我们在客户端执行 ifconfig 命令时,第一次返回的不全(1024字节),在执行 ls 命令时,返回的是 ifconfig 剩下的命令(1024字节),如下

>>:ifconfig
recv: lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
    options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
    inet 127.0.0.1 netmask 0xff000000 
    inet6 ::1 prefixlen 128 
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
    nd6 options=201<PERFORMNUD,DAD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
ap1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
    options=400<CHANNEL_IO>
    ether b2:9c:4a:c4:34:e7 
    media: autoselect
    status: inactive
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=400<CHANNEL_IO>
    ether 90:9c:4a:c4:34:e7 
    inet6 fe80::18f2:9b2f:4496:675e%en0 prefixlen 64 secured scopeid 0x6 
    inet 192.168.31.110 netmask 0xffffff00 broadcast 192.168.31.255
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect
    status: active
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
    options=400<CHANNEL_IO>
    ether 02:9c:4a:c4:34:e7 
    media: autoselect
    status: inactive
awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484
    opti
>>:ls
recv: ons=400<CHANNEL_IO>
    ether e2:3f:ba:ac:28:1d 
    inet6 fe80::e03f:baff:feac:281d%awdl0 prefixlen 64 scopeid 0x8 
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect
    status: active
llw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=400<CHANNEL_IO>
    ether e2:3f:ba:ac:28:1d 
    inet6 fe80::e03f:baff:feac:281d%llw0 prefixlen 64 scopeid 0x9 
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect
    status: active
en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=460<TSO4,TSO6,CHANNEL_IO>
    ether 1e:66:6c:14:0d:c4 
    media: autoselect <full-duplex>
    status: inactive
en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=460<TSO4,TSO6,CHANNEL_IO>
    ether 1e:66:6c:14:0d:c5 
    media: autoselect <full-duplex>
    status: inactive
en3: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=460<TSO4,TSO6,CHANNEL_IO>
    ether 1e:66:6c:14:0d:c1 
    media: autoselect <full-duplex>
    status: inactive
en4: flags=8963<U


全部接收


先判断需要接收的数据,然后接收的和实际的对比,如果小于实际的,继续接收,否则,打印出接收的大小和命令

客户端

import socket
client = socket.socket()
client.connect(('localhost', 9999))
while True:
    msg = input(">>:").strip()
    if len(msg) == 0:
        continue
    client.send(msg.encode("utf-8"))
    data_size = client.recv(1024)  # 接收命令的长度
    print('需要接收的数据大小:', data_size)
    client.send('开始发吧'.encode('utf-8'))  # 处理黏包
    reve_size = 0
    reve_data = b''
    while reve_size < int(data_size.decode()):  # data_size是byte类型
        data = client.recv(1024)
        reve_size += len(data)  # 每次收到的有可能小于1024,所以必须用len判断
        reve_data += data
    else:
        print('接收到的大小:', reve_size)
        print(reve_data.decode())
client.close()

服务端

import socket, os
server = socket.socket()
server.bind(('localhost', 9999))
server.listen()
while True:
    conn, addr = server.accept()
    print('new conn', addr)
    while True:
        print('等待新指令')
        data = conn.recv(1024)
        if not data:
            print('客户端已断开')
            break
        print('执行指令:', data)
        cmd_res = os.popen(data.decode()).read()  # 执行输入的命令,decode转换为字符串
        print('数据的大小:', len(cmd_res))
        if len(cmd_res) == 0:
            cmd_res = 'cmd has no out'
        conn.send(str(len(cmd_res.encode())).encode('utf-8'))  # 数字不能encode。cmd_res.encode()将汉字转换成3个字节,不转发送的大小和接收的大小不一样
        conn.recv(1024)  # 处理黏包
        conn.send(cmd_res.encode('utf-8'))  # 转为 utf-8发过去

相关文章
|
2月前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
在数字时代,网络应用成为连接世界的桥梁。Python凭借简洁的语法和丰富的库支持,成为开发高效网络应用的首选。本文通过实时聊天室案例,介绍Python Socket编程的基础与进阶技巧。基础篇涵盖服务器和客户端的建立与数据交换;进阶篇则探讨多线程与异步IO优化方案,助力提升应用性能。通过本案例,你将掌握Socket编程的核心技能,推动网络应用飞得更高、更远。
55 1
|
1月前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
129 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
1月前
|
JSON 数据格式 Python
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
本文介绍了如何使用Python的socket模块实现客户端到服务器端的文件传输,包括客户端发送文件信息和内容,服务器端接收并保存文件的完整过程。
135 1
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
|
19天前
|
Kubernetes 网络协议 Python
Python网络编程:从Socket到Web应用
在信息时代,网络编程是软件开发的重要组成部分。Python作为多用途编程语言,提供了从Socket编程到Web应用开发的强大支持。本文将从基础的Socket编程入手,逐步深入到复杂的Web应用开发,涵盖Flask、Django等框架的应用,以及异步Web编程和微服务架构。通过本文,读者将全面了解Python在网络编程领域的应用。
18 1
|
28天前
|
消息中间件 监控 网络协议
Python中的Socket魔法:如何利用socket模块构建强大的网络通信
本文介绍了Python的`socket`模块,讲解了其基本概念、语法和使用方法。通过简单的TCP服务器和客户端示例,展示了如何创建、绑定、监听、接受连接及发送/接收数据。进一步探讨了多用户聊天室的实现,并介绍了非阻塞IO和多路复用技术以提高并发处理能力。最后,讨论了`socket`模块在现代网络编程中的应用及其与其他通信方式的关系。
|
1月前
|
安全 网络协议 网络安全
Python Socket编程大揭秘:从菜鸟到黑客的进阶之路,你准备好了吗?
【10月更文挑战第4天】在编程领域,Python Socket编程犹如一把开启网络世界的钥匙,带领开发者从简单数据传输迈向复杂应用构建。本文将引导你从零开始,逐步掌握Socket编程的核心技巧,包括基本概念、TCP服务器与客户端的搭建、并发处理及异常管理、SSL/TLS加密通信,直至深入了解网络协议与安全漏洞。通过实战演练与理论学习,助你成为驾驭网络世界的高手。
34 1
|
1月前
|
存储 网络协议 Linux
聊一聊 Python 的 socket,以及 select、poll、epoll 又是怎么一回事?
聊一聊 Python 的 socket,以及 select、poll、epoll 又是怎么一回事?
119 2
|
2月前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
在数字宇宙中,网络如同复杂脉络连接每个角落,Python Socket编程则是开启这一世界的钥匙。本文将引导你从基础概念入手,逐步掌握Socket编程,并通过实战示例构建TCP/UDP服务器与客户端。你将学会使用Python的socket模块进行网络通信,了解TCP与UDP的区别,并运用多线程与异步IO提升服务器性能。跟随本文指引,成为网络世界的建筑师,构建自己的网络帝国。
35 2
|
2月前
|
网络协议 Python
告别网络编程迷雾!Python Socket编程基础与实战,让你秒变网络达人!
在网络编程的世界里,Socket编程是连接数据与服务的关键桥梁。对于初学者,这往往是最棘手的部分。本文将用Python带你轻松入门Socket编程,从创建TCP服务器与客户端的基础搭建,到处理并发连接的实战技巧,逐步揭开网络编程的神秘面纱。通过具体的代码示例,我们将掌握Socket的基本概念与操作,让你成为网络编程的高手。无论是简单的数据传输还是复杂的并发处理,Python都能助你一臂之力。希望这篇文章成为你网络编程旅程的良好开端。
55 3
|
2月前
|
网络协议 开发者 Python
网络编程小白秒变大咖!Python Socket基础与进阶教程,轻松上手无压力!
在网络技术飞速发展的今天,掌握网络编程已成为开发者的重要技能。本文以Python为工具,带你从Socket编程基础逐步深入至进阶领域。首先介绍Socket的概念及TCP/UDP协议,接着演示如何用Python创建、绑定、监听Socket,实现数据收发;最后通过构建简单的聊天服务器,巩固所学知识。让初学者也能迅速上手,成为网络编程高手。
72 1