本文目录:

一、TCP通讯模板

二、远程CMD程序

三、解决粘包问题

四、解决粘包问题2

一、TCP通讯模板

TCP客户端

import socket

c = socket.socket()

# 连接服务器
c.connect(("127.0.0.1",65535)) while True:
# 发送数据
msg = input(">>>:")
if not msg:continue
c.send(msg.encode("utf-8"))
print("send!")
# 收数据
data = c.recv(1024).decode("utf-8")
print("receiver!")
print(data) # 关闭资源
c.close()

TCP服务器

import socket
# 使用TCP 可以直接默认
server = socket.socket() # 指定端口 和 ip 端口 0 - 1023是系统保留的
server.bind(("127.0.0.1",65535)) # 监听请求 参数为最大半连接数(三次握手未完成的请求 可能是服务器来不及 客户端恶意攻击)
server.listen(5)
# 为了可以不断的接受客户端连接请求
while True:
# 接受连接请求
c,addr = server.accept()
# 为了可以重复收发数据
while True:
try:
# 1024 程序的最大缓冲区容量 返回值类型为bytes类型
data = c.recv(1024).decode("utf-8")
# 如果客户端断开连接(客户端调用了close) recv 返回值为空 此时应该结束循环
if not data:# 在linux中 客户端异常关闭 服务器也会收空
print("client closed!")
c.close()
break
#解码
print(data)
# 回复数据 将原始数据转为大写
c.send(data.upper().encode("utf-8"))
except ConnectionResetError:
print("客户端异常关闭!!")
c.close()
break
# 关闭资源
server.close() # TCP断开连接的正确姿势
# 客户端调用close
# 服务器判断如果接收数据为空则相应的调用close

二、远程CMD程序

CMD客户端

import socket

c = socket.socket()

# 连接服务器
c.connect(("127.0.0.1",65535)) while True:
# 发送数据
msg = input(">>>:")
if not msg:continue
c.send(msg.encode("utf-8"))
# while True:
# # 收数据
data = c.recv(1024).decode("gbk")
print(data) # 关闭资源
c.close() # 问题? 服务器发送的数据超过了接收端缓冲区大小 可直接修改大小来满足服务器传输的大小 但是不长远
# 上述问题 称之为粘包
# 思考: 循环每次读取一小部分 直到取完为止
# 什么时候可以结束循环 前提是让客户端直知道你的数据到底有多长
# 正确思路:
"""
发送方
1.先告诉对方你要发的数据的长度
2.在发送真实数据 接收方
1.先接收数据的长度信息
2.根据长度信息循环获取直到以获取的长度等于总长度 """

CMD客户端2

import socket,time

c = socket.socket()

# 连接服务器
c.connect(("127.0.0.1",65535)) while True:
# 发送数据 c.send("dir".encode("utf-8"))
time.sleep(1)
c.send("dir".encode("utf-8")) data = c.recv(1024).decode("gbk")
print(data) # 关闭资源
c.close() # 问题2 当客户端连续两行代码都发送一个dir时 服务器收到了一个dirdir
# 两个命令黏在一起
# TCP协议内的一个nagle算法 如果数据量小 并且时间间隔短会将数据合并一个包

CMD服务器

#  1.服务器先启动 -> 客户端发送指令 -> 服务器接收后使用subprocess执行命令->将执行结果返回给客户端

import socket,subprocess
# 使用TCP 可以直接默认
server = socket.socket() # 指定端口 和 ip 端口 0 - 1023是系统保留的
server.bind(("127.0.0.1",65535)) # 监听请求 参数为最大半连接数(三次握手未完成的请求 可能是服务器来不及 客户端恶意攻击)
server.listen(5)
# 为了可以不断的接受客户端连接请求
while True:
# 接受连接请求
c,addr = server.accept()
# 为了可以重复收发数据
while True:
try:
# 1024 程序的最大缓冲区容量 返回值类型为bytes类型
cmd = c.recv(1024).decode("utf-8")
# 如果客户端断开连接(客户端调用了close) recv 返回值为kong 此时应该结束循环
if not cmd:# 在linux中 客户端异常关闭 服务器也会收空
print("client closed!")
c.close()
break
#解码
print(cmd)
# 执行命令
p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# 将错误信息和正确信息拼接到一起
res = p.stdout.read() + p.stderr.read()
print("执行结果长",len(res))
# 将执行结果发送给客户端
c.send(res)
except ConnectionResetError:
print("客户端异常关闭!!")
c.close()
break
# 关闭资源
server.close() # TCP断开连接的正确姿势
# 客户端调用close
# 服务器判断如果接收数据为空则相应的调用close

三、解决粘包问题

CMD客户端

import socket,struct

c = socket.socket()

# 连接服务器
c.connect(("127.0.0.1",65535)) while True:
# 发送数据
msg = input(">>>:")
if not msg:continue
c.send(msg.encode("utf-8")) # 1.先获取长度
bytes_len = c.recv(4) #对方是i格式 固定4字节
# 2.转回整型
total_len = struct.unpack("i",bytes_len)[0]
# 已经接收的长度
recv_len = 0
# 一个表示最终数据的bytes
finally_data = b''
# 3.收到的长度小于总长度就继续
while recv_len < total_len:
# 循环收数据
data = c.recv(1024)
recv_len += len(data)
finally_data += data
# 整体解码
print(finally_data.decode("gbk")) # 关闭资源
c.close() # 问题? 服务器发送的数据超过了接收端缓冲区大小 可直接修改大小来满足服务器传输的大小 但是不长远
# 上述问题 称之为粘包
# 思考: 循环每次读取一小部分 直到取完为止
# 什么时候可以结束循环 前提是让客户端直知道你的数据到底有多长
# 正确思路:
"""
发送方
1.先告诉对方你要发的数据的长度
2.在发送真实数据 接收方
1.先接收数据的长度信息
2.根据长度信息循环获取直到以获取的长度等于总长度 自定义报头未讲
"""

CMD服务器

#  1.服务器先启动 -> 客户端发送指令 -> 服务器接收后使用subprocess执行命令->将执行结果返回给客户端

import socket,subprocess,struct
# 使用TCP 可以直接默认
server = socket.socket() # 指定端口 和 ip 端口 0 - 1023是系统保留的
server.bind(("127.0.0.1",65535)) # 监听请求 参数为最大半连接数(三次握手未完成的请求 可能是服务器来不及 客户端恶意攻击)
server.listen(5)
# 为了可以不断的接受客户端连接请求
while True:
# 接受连接请求
c,addr = server.accept()
# 为了可以重复收发数据
while True:
try:
# 1024 程序的最大缓冲区容量 返回值类型为bytes类型
cmd = c.recv(1024).decode("utf-8")
# 如果客户端断开连接(客户端调用了close) recv 返回值为kong 此时应该结束循环
if not cmd:# 在linux中 客户端异常关闭 服务器也会收空
print("client closed!")
c.close()
break
#解码
print(cmd)
# 执行命令
p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# 将错误信息和正确信息拼接到一起
res = p.stdout.read() + p.stderr.read()
print("执行结果长",len(res)) # 1.先发送数据的长度
data_len = len(res)
# 长度是一个整型 需要转为字节 1000 b'\x001' 2000 b'\x001\x002'
# 另外 需要保证 长度信息转换后的结果长度是固定的 否则客户端也会粘包(不知道取多少字节)
# struct 模块负责将python中的数据类型 转为c语言中结构体
# 整型转字节
bytes_len = struct.pack("i",data_len)
c.send(bytes_len)
# 2.发送真实数据
c.send(res)
except ConnectionResetError:
print("客户端异常关闭!!")
c.close()
break
# 关闭资源
server.close() # TCP断开连接的正确姿势
# 客户端调用close
# 服务器判断如果接收数据为空则相应的调用close

#structTest.py文件

import struct

# 整型转字节  i 表示int 长度为4字节   q表示long int 长度为8字节
print(len(struct.pack("q",10240000000))) # 字节转整型 得到一个元祖
print(struct.unpack("q",struct.pack("q",10240000000))[0])

四、解决粘包问题2

CMD客户端

import socket,struct,json

c = socket.socket()

# 连接服务器
c.connect(("127.0.0.1",65535)) while True:
# 发送数据
msg = input(">>>:")
if not msg:continue
c.send(msg.encode("utf-8")) # 1.先获取报头长度
bytes_len = c.recv(4) #对方是i格式 固定4字节
# 2.转回整型
head_len = struct.unpack("i",bytes_len)[0] # 3.接受报头数据
head_bytes = c.recv(head_len)
# 4.转为json字符串 并转为字典
head_dic = json.loads(head_bytes.decode("utf-8"))
print(head_dic) # 已经接收的长度
recv_len = 0
# 一个表示最终数据的bytes
finally_data = b''
# 3.收到的长度小于总长度就继续
while recv_len < head_dic["total_size"]:
# 循环收数据
data = c.recv(1024)
recv_len += len(data)
finally_data += data
# 整体解码
print(finally_data.decode("gbk")) # 关闭资源
c.close() # 问题? 服务器发送的数据超过了接收端缓冲区大小 可直接修改大小来满足服务器传输的大小 但是不长远
# 上述问题 称之为粘包
# 思考: 循环每次读取一小部分 直到取完为止
# 什么时候可以结束循环 前提是让客户端直知道你的数据到底有多长
# 正确思路:
"""
发送方
1.先告诉对方你要发的数据的长度
2.在发送真实数据 接收方
1.先接收数据的长度信息
2.根据长度信息循环获取直到以获取的长度等于总长度 自定义报头未讲
"""

CMD服务器

#  1.服务器先启动 -> 客户端发送指令 -> 服务器接收后使用subprocess执行命令->将执行结果返回给客户端

import socket,subprocess,struct,json
# 使用TCP 可以直接默认
server = socket.socket() # 指定端口 和 ip 端口 0 - 1023是系统保留的
server.bind(("127.0.0.1",65535)) # 监听请求 参数为最大半连接数(三次握手未完成的请求 可能是服务器来不及 客户端恶意攻击)
server.listen(5)
# 为了可以不断的接受客户端连接请求
while True:
# 接受连接请求
c,addr = server.accept()
# 为了可以重复收发数据
while True:
try:
# 1024 程序的最大缓冲区容量 返回值类型为bytes类型
cmd = c.recv(1024).decode("utf-8")
# 如果客户端断开连接(客户端调用了close) recv 返回值为kong 此时应该结束循环
if not cmd:# 在linux中 客户端异常关闭 服务器也会收空
print("client closed!")
c.close()
break
#解码
print(cmd)
# 执行命令
p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# 将错误信息和正确信息拼接到一起
res = p.stdout.read() + p.stderr.read()
print("执行结果长",len(res)) # 1.组装一个报头信息
head_dic = {
"name":"仓老师视频教学 如何做炸鸡!",
"md5":"asasasasaas",
"total_size":len(res),
"type":"video"
}
# 2.转json字符串
head_str = json.dumps(head_dic)
# 3.转字节
head_bytes = head_str.encode("utf-8")
# 4.发送报头长度
bytes_len = struct.pack("i",len(head_bytes))
c.send(bytes_len)
# 5.发送报头
c.send(head_bytes)
# 6.发送真实数据
c.send(res) except ConnectionResetError:
print("客户端异常关闭!!")
c.close()
break
# 关闭资源
server.close() # TCP断开连接的正确姿势
# 客户端调用close
# 服务器判断如果接收数据为空则相应的调用close

# structTest.py文件

import struct

# 整型转字节  i 表示int 长度为4字节   q表示long int 长度为8字节
print(len(struct.pack("q",10240000000))) # 字节转整型 得到一个元祖
print(struct.unpack("q",struct.pack("q",10240000000))[0])

python网络编程:TCP通讯模板、粘包及解决方案、自定义报头的更多相关文章

  1. Python网络编程(2)-粘包现象及socketserver模块实现TCP并发

    1. 基于Tcp的远程调用命令实现 很多人应该都使用过Xshell工具,这是一个远程连接工具,通过上面的知识,就可以模拟出Xshell远程连接服务器并调用命令的功能. Tcp服务端代码如下: impo ...

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

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

  3. TCP通讯处理粘包详解

    TCP通讯处理粘包详解 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据.TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的 ...

  4. python 网络编程 TCP/IP socket UDP

    TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...

  5. 网络编程3 网络编程之缓冲区&subprocess&粘包&粘包解决方案

    1.sub简单使用 2.粘包现象(1) 3.粘包现象(2) 4.粘包现象解决方案 5.struct学习 6.粘包现象升级版解决方案 7.打印进度条

  6. 第二十八天- tcp下的粘包和解决方案

    1.什么是粘包 写在前面:只有TCP有粘包现象,UDP永远不会粘包 1.TCP下的粘包 因为TCP协议是面向连接.面向流的,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个 ...

  7. python网络编程 - tcp

    网络编程 低级别的网络服务 高级别的网络服务 socket又称“套接字”,应用程序通过“套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. tcp 传输控制协议(Tra ...

  8. python------Socket网络编程(二)粘包问题

    一.socket网络编程 粘包:服务端两次发送指令在一起,它会把两次发送内容合在一起发送,称为粘包,从而出现错误. 解决方法:(比较low的方法) 有些需要实时更新的,用sleep有延迟,不能这样解决 ...

  9. python---基础知识回顾(六)网络编程2(处理粘包)

    前戏: 之前在python---基础知识回顾(六)网络编程异步模块中提到过粘包现象,而且在使用twisted中提到过一种处理办法,按行接收lineReceived,当收到\r\n换行符时,才去缓冲区中 ...

  10. python 网络编程 -- Tcp协议

    Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可. 客户端 大多数连接都是可靠 ...

随机推荐

  1. 树莓派-Ubuntu Mate开启ssh服务

    1. 运行 apt search openssh-server 查看是否安装ssh服务. 2. 如已安装,运行 sudo dpkg-reconfigure openssh-server 重新配置shh ...

  2. centos7安装redis3.2.5集群

    安装参照     https://blog.csdn.net/mingliangniwo/article/details/54600640  https://blog.csdn.net/u013820 ...

  3. Asp.net Core深入一:数据库访问(Mysql为例)

    一.数据库概述 1.一个DBContext操纵一个数据库 2.DbContext下的一个DbSet<Model类>关联一个表,但是也可以只写一个表,DbContext可以关联其他的表. 3 ...

  4. 【POJ - 1703】Find them, Catch them(种类并查集)

    Find them, Catch them 直接翻译了 Descriptions 警方决定捣毁两大犯罪团伙:龙帮和蛇帮,显然一个帮派至少有一人.该城有N个罪犯,编号从1至N(N<=100000. ...

  5. sql内联注入

    测试字符串 变    种 预 期 结 果 ' 触发错误.如果成功,数据库将返回一个错误 1' or '1'='1 1') or ('1'='1 永真条件.如果成功,将返回表中所有的行 value' o ...

  6. Macaca环境搭建(四)----mac系统macaca安装

    一.安装Homebrew 命令:/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/insta ...

  7. Linux 打包QT程序到未安装QT的其他Linux主机下运行

    昨天终于改好了一个开源但是用起来有问题的串口调试助手,想把它打包一下以后在其他电脑上也可以用. 找了网上的一个教程打包后,在本机上可以正常使用,但是移植到另一台上就出现缺少xcb的提示. 上网搜资料倒 ...

  8. PTA(Advanced Level)1075.PAT Judge

    The ranklist of PAT is generated from the status list, which shows the scores of the submissions. Th ...

  9. PTA(Advanced Level)1025.PAT Ranking

    To evaluate the performance of our first year CS majored students, we consider their grades of three ...

  10. iview Message(全局提示)与Notice(通知提醒)全局配置方法

    在使用iview 的Message与Notice组件时,可以对提示框的显示位置与显示时长进行配置. iview提供了两个配置属性.分别是: top 提示组件距离顶端的距离,单位像素. duration ...