本文目录:

一、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. 编译安装了的nginx 添加http_ssl_module模块

    1.看下编译安装nginx的时候,都编译安装的哪些模块. [root@zabbix ~]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1. ...

  2. 5.Linux文件权限

    Linux用户类别 root:这是系统特权用户类,他们都有访问root登录账号的权限 owner:这是实际拥有文件的用户 group:这是共享文件的组访问权的用户类的用户组名称 world:这是不属于 ...

  3. 安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置

    1.下载和安装OpenCV SDK     VS2010不用说,肯定都安装了吧.来说说当前最新的OpenCV版本2.4.8(2014年2月24日),2.4.9 (2014年4月)的下载和安装.与其说是 ...

  4. Linux文件属性拓展知识

    文件删除恢复ext3grep,应该多养成好习惯,先备份在操作:要能快速还原,不容易还原,先通过多套测试环境测试,然后在操作. 企业面试题: 一个100M(100000K)的磁盘分区,分别写入1K的文件 ...

  5. Nginx整合Tomcat

    现在先不考虑集群的配置问题,只实现Nginx实现一台tomact的代理 1.我们需要一个web项目,这里我把先准备好的web.war文件部署到Tomact服务器上 mvn clean install ...

  6. java集合List解析

    作为一个Developer,Java集合类是我们在工作中运用最多的.最频繁的类.相比于数组(Array)来说,集合类的长度可变,更加适合于现代开发需求: Java集合就像一个容器,可以存储任何类型的数 ...

  7. ByteArrayInputStream类

    一.说明 哈哈,这是学习Java之路的第一篇博文.虽然说接触学习Java有一段时间了,但是对流的概念一直并不是很清楚.也看了很多资料,但是感觉还是非常的抽象很难去理解.但是流又是Java中很重要的一部 ...

  8. Java回调实现异步 (转)

    出处: Java回调实现异步 在正常的业务中使用同步线程,如果服务器每处理一个请求,就创建一个线程的话,会对服务器的资源造成浪费.因为这些线程可能会浪费时间在等待网络传输,等待数据库连接等其他事情上, ...

  9. 简易计算器-leetcode

    今天,开始在leetcode上面开始做题,第一个题目是: Implement a basic calculator to evaluate a simple expression string. Th ...

  10. IIS Express启动不了的的解决方案

    netsh http show iplisten netsh http delete iplisten ipaddress=11.22.33.44 (where 11.22.33.44 is the ...