无注释版

os.popen()模式

server端

import socket
import os phone = socket.socket()
phone.bind(("localhost",8088))
phone.listen() while 1:
conn,addr = phone.accept()
while 1:
try:
from_client_data = conn.recv(1024)
if from_client_data.upper() == b'Q':
print("客户端退出")
break
print(from_client_data.decode('utf-8'))
cmd_res = os.popen(from_client_data.decode("utf-8")).read()
if len(cmd_res) == 0:
cmd_res = "cmd hs no output..."
print(len(cmd_res.encode('gbk')))
conn.send(str(len(cmd_res.encode('gbk'))).encode('gbk'))
client.ack = conn.recv(1024)
conn.send(cmd_res.encode('gbk'))
except ConnectionResetError:
break
conn.close()
phone.close()

client端

import socket
phone = socket.socket()
phone.connect(('localhost',8088))
while 1:
client_data = input(">>>")
if not client_data:
print("发送的内容不能为空")
continue
phone.send(client_data.encode("utf-8"))
if client_data.upper() == "Q":
quit()
else:
server_data = phone.recv(1024)
phone.send("准备好接收了".encode('utf-8'))
total_size = int(server_data.decode('gbk'))
total_data = b''
while 1:
if len(total_data) < total_size:
total_data += phone.recv(1024)
print(len(total_data))
else:
break
print(total_data.decode('gbk'))
phone.close()

struct模块解决粘包

server端

import socket
import subprocess
import struct phone = socket.socket()
phone.bind(("localhost",8088))
phone.listen(5) while 1:
conn,addr = phone.accept()
print(addr)
while 1:
try:
from_client_data = conn.recv(1024)
if from_client_data.upper() == b'Q':
print("客户端退出")
break
print(from_client_data.decode('utf-8'))
obj = subprocess.Popen(from_client_data.decode('utf-8'),
shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,)
ret = obj.stdout.read()+obj.stderr.read()
total_size = len(ret)
header = struct.pack('i',total_size)
print(total_size)
conn.send(header)
conn.send(ret)
except ConnectionResetError:
break
conn.close()
phone.close()

client端

import socket
import struct
phone = socket.socket()
phone.connect(('localhost',8088))
while 1:
client_data = input(">>>")
if not client_data:
print("发送的内容不能为空")
continue
phone.send(client_data.encode("utf-8"))
if client_data.upper() == "Q":
quit()
else:
server_data = phone.recv(4)
total_size = struct.unpack('i',server_data)[0]
total_data = b''
while 1:
if len(total_data) < total_size:
total_data += phone.recv(1024)
print(len(total_data))
else:
break
print(total_data.decode('gbk'))
# print(int(server_data.decode('gbk')))
phone.close()

有注释版

os.popen()模式

server端

import socket
import os phone = socket.socket() # 实例化一个socket对象 phone.bind(("localhost",8088)) # 绑定地址(host,port)到套接字,在AF_INET下,以元组(host,port)的形式表示地址 phone.listen(5) # 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 while 1: # 开启循环,多个用户同时连接(当然不是并发,排队连接)
conn,addr = phone.accept() # 被动接受TCP客户端连接,(阻塞式)等待连接的到来,会有两个值,conn我也不明白是什么值,addr是客户端连接的地址 while 1: # 客户端与服务端多次对话,客户端多次执行循环
try: # 异常处理,客户端直接退出ConnectionResetError错误
from_client_data = conn.recv(1024) # 接收客户端数据
if from_client_data.upper() == b'Q':
# 判断客户端输入是否是q或Q,如果是q,直接退出当前连接
print("客户端退出")
break
print(from_client_data.decode('utf-8')) # 输出客户端转码后的数据
cmd_res = os.popen(from_client_data.decode("utf-8")).read() # 执行os命令,通过popen执行cmd命令
if len(cmd_res) == 0: # 如果没有该命令,返回下面结果
cmd_res = "cmd hs no output..."
conn.send(str(len(cmd_res.encode('gbk'))).encode('gbk')) # 发送数据,首先计算cmd_res的gbk字节长度,然后转换成字符串发送给客户端,因为int型不能发送
print(len(cmd_res.encode('gbk'))) # 输出该命令返回的长度
conn.send(cmd_res.encode('gbk')) # 执行一个接收,截断上下两个的粘包
conn.send(cmd_res.encode('gbk')) # 发送给客户端
except ConnectionResetError:
break
conn.close() # 关闭连接
phone.close() # 关闭连接

client端

import socket
phone = socket.socket() # 实例化对象
phone.connect(('localhost',8088)) # 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
while 1: # 循环输入
client_data = input(">>>")
if not client_data: # 如果输入为空,not client_data 则为True
print("发送的内容不能为空")
continue
phone.send(client_data.encode("utf-8")) # 给服务端发送信息
if client_data.upper() == "Q": # q退出
quit()
else:
server_data = phone.recv(1024) # 接收返回的字节长度
phone.send("准备好接收了".encode('utf-8')) # 给服务端发送消息,阻塞服务端上下造成粘包的问题(low版)
total_size = int(server_data.decode('gbk')) # 接收到的是字符串,转换成整型
total_data = b'' # 刚开始设置为0,空字符串则为0,前面加b表示字节
while 1: # 如果我收到的字节小于total_size,则一直循环
if len(total_data) < total_size:
total_data += phone.recv(1024) # 每次把信息加到total_data中
print(len(total_data))
else:
break
print(total_data.decode('gbk')) # 输出返回的结果
phone.close() # 关闭连接

struct模块解决粘包

server端

import socket
import subprocess
import struct phone = socket.socket() # 实例化一个socket对象
phone.bind(("localhost",8088))
# 绑定地址(host,port)到套接字,在AF_INET下,以元组(host,port)的形式表示地址
phone.listen(5)
# 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 while 1:# 开启循环,多个用户同时连接(当然不是并发,排队连接) conn,addr = phone.accept() # 被动接受TCP客户端连接,(阻塞式)等待连接的到来,会有两个值,conn我也不明白是什么值,addr是客户端连接的地址
print(addr)
while 1: # 客户端与服务端多次对话,客户端多次执行循环
try: # 异常处理,客户端直接退出ConnectionResetError错误
from_client_data = conn.recv(1024) # 接收客户端数据
if from_client_data.upper() == b'Q': # 判断客户端输入是否是q或Q,如果是q,直接退出当前连接
print("客户端退出")
break
print(from_client_data.decode('utf-8')) # 输出客户端转码后的数据
obj = subprocess.Popen(from_client_data.decode('utf-8'),
shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,)
# subprocess 模块中的代码
# shell: 命令解释器,相当于调用cmd 执行指定的命令。
# stdout:正确结果丢到管道中。
# stderr:错了丢到另一个管道中。
# windows操作系统的默认编码是gbk编码。
ret = obj.stdout.read()+obj.stderr.read() # 加的是字节
# 正确的输出跟错误的输出加起来,因为正确输出时,错误输出为空,所以加起来相当于0+1,没什么区别
total_size = len(ret) # 计算返回命令的长度
header = struct.pack('i',total_size) # 将一个数字转化成等长度的bytes类型。
print(total_size) # 打印出返回命令的长度
conn.send(header) # 发送固定长度的报头
conn.send(ret) # 给客户端发送返回命令的结果
except ConnectionResetError:
break
conn.close() # 关闭连接
phone.close() # 关闭连接

client端

import socket
import struct
phone = socket.socket() # 实例化对象
phone.connect(('localhost',8088)) # 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
while 1: # 循环输入
client_data = input(">>>")
if not client_data: # 如果输入为空,not client_data 则为True
print("发送的内容不能为空")
continue
phone.send(client_data.encode("utf-8")) # 给服务端发送信息
if client_data.upper() == "Q": # q退出
quit()
else:
server_data = phone.recv(4) # 接收报头长度
total_size = struct.unpack('i',server_data)[0] # 反解报头
total_data = b'' # 刚开始设置为0,空字符串则为0,前面加b表示字节
while 1: # 如果我收到的字节小于total_size,则一直循环
if len(total_data) < total_size:
total_data += phone.recv(1024) # 每次把信息加到total_data中
print(len(total_data))
else:
break
print(total_data.decode('gbk')) # 输出返回的结果,windows默认gbk
# print(int(server_data.decode('gbk')))
phone.close() # 关闭连接

解决socket粘包的两种low版模式 os.popen()和struct模块的更多相关文章

  1. 解决Socket粘包问题——C#代码

    解决Socket粘包问题——C#代码 前天晚上,曾经的一个同事问我socket发送消息如果太频繁接收方就会有消息重叠,因为当时在外面,没有多加思考 第一反应还以为是多线程导致的数据不同步导致的,让他加 ...

  2. C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)

    介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...

  3. Socket粘包问题终极解决方案—Netty版(2W字)!

    上一篇我们讲了<Socket粘包问题的3种解决方案>,但没想到评论区竟然炸了.介于大家的热情讨论,以及不同的反馈意见,本文就来做一个扩展和延伸,试图找到问题的最优解,以及消息通讯的最优解决 ...

  4. 网络编程基础【day09】:解决socket粘包之大数据(七)

    本节内容 概述 linux下运行效果 sleep解决粘包 服务端插入交互解决粘包问题 一.概述 刚刚我们在window的操作系统上,很完美的解决了,大数据量的数据传输出现的问题,但是在Linux环境下 ...

  5. 解决tcp粘包问题

    目录 什么是粘包(演示粘包现象) 解决粘包 实际应用 什么是粘包 首先只有tcp有粘包现象,udp没有粘包 socket收发消息的原理 发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地 ...

  6. python套接字解决tcp粘包问题

    python套接字解决tcp粘包问题 目录 什么是粘包 演示粘包现象 解决粘包 实际应用 什么是粘包 首先只有tcp有粘包现象,udp没有粘包 socket收发消息的原理 发送端可以是一K一K地发送数 ...

  7. python网络编程基础之socket粘包现象

    粘包现象两种 登陆 #服务端import json import socket server=socket.socket()#创建socket对象 ip_port=('127.0.0.1',8001) ...

  8. socket粘包现象加解决办法

    socket粘包现象分析与解决方案 简单远程执行命令程序开发(内容回顾) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=su ...

  9. Socket粘包问题的3种解决方案,最后一种最完美!

    在 Java 语言中,传统的 Socket 编程分为两种实现方式,这两种实现方式也对应着两种不同的传输层协议:TCP 协议和 UDP 协议,但作为互联网中最常用的传输层协议 TCP,在使用时却会导致粘 ...

随机推荐

  1. c++学习书籍推荐《C++设计新思维》下载

    百度云及其他网盘下载地址:点我 译序by 侯捷 i 译序by 於春景 iii 目录 v 序言by scott meyers xi 序言by john vlissides xv 前言 xvii 致谢 x ...

  2. @ImportResource导入的xml配置里的Bean能够使用@PropertySource导入的属性值吗?

    每篇一句 大师都是偏执的,偏执才能产生力量,妥协是没有力量的.你对全世界妥协了你就是空气.所以若没有偏见,哪来的大师呢 相关阅读 [小家Spring]详解PropertyPlaceholderConf ...

  3. C#窗体实现打开关闭VM虚拟机

    vixclass.cs//定义开机.关机等函数 using System; using System.Collections.Generic; using System.Linq; using Sys ...

  4. [PTA] 数据结构与算法题目集 6-1 单链表逆转

    List Reverse(List L) { List p, q; p = L; q = L; L = NULL; while (p) { p = p->Next; q->Next = L ...

  5. Java 读写 excel 实战完全解析

    本文微信公众号「AndroidTraveler」首发. 背景 时值毕业季,很多毕业生初入职场. 因此,这边也写了一些新手相关的 Android 技术点. 比如上一篇的 Android 开发你需要了解的 ...

  6. java中代码的注释和快捷

    添加必要的注释,对一个有责任心.有道德模范的前端必须具备的好习惯, 可以大大提高代码的可维护性.可读性. java代码注释快捷键:ctrl+shift+/首先熟悉一下html.css.js的注释的写法 ...

  7. handlerAdapter与方法调用(参数的解析)

    前提:当找到handler以后,那么就要让handler发挥作用,这个时候handlerAdapter就派上用场了 这里面比较复杂就是requestMappingHandlerAdapter了,其他的 ...

  8. ESP-8266 RTOS 环境搭建

    本节为 ESP-8266 RTOS 的环境搭建 只适合Linux环境,推荐Ubuntu.本例以Ubuntu16.04-x64为例 安装 git [dzlua@ubuntu: ~]$ sudo apt ...

  9. JS中构造函数和普通函数有什么区别

    JS中构造函数有普通函数有什么区别? 1.一般规则 构造函数都应该以 一个大写字母开头,eg: function Person(){...} 而非构造函数则应该以一个小写字母开头,eg: functi ...

  10. 机器学习经典分类算法 —— k-均值算法(附python实现代码及数据集)

    目录 工作原理 python实现 算法实战 对mnist数据集进行聚类 小结 附录 工作原理 聚类是一种无监督的学习,它将相似的对象归到同一个簇中.类似于全自动分类(自动的意思是连类别都是自动构建的) ...