CSIC_716_20191205【TCP-解决粘包问题、UDP模板】
------------------------------------------------------------------------------------------------------------------------------------
客户端代码模板:(以ssh为例)
# _*_ coding: gbk _*_
# @Author: Wonder import socket
import json
import struct client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('172.16.10.19', 9527)) while True:
try:
cmd = input('>>>请输入指令').strip()
if not cmd:
continue
if cmd == 'q':
break
cmd = cmd.encode('utf-8')
dict_context = {
'data_size': len(cmd) # 二进制的长度
}
client_bytes = json.dumps(dict_context).encode('utf-8') # dict----->json------->binary 报头
head = struct.pack('i', len(client_bytes)) # struct 将报头长度巧妙的转为4 bit # 以下为一波socket三连发送操作。
client.send(head) # 发报头长度, client.send(client_bytes) # 发报头,里面有实际数据的长度 client.send(cmd) # 传数据 bin_head = client.recv(4) # 接收来自server的报头信息
json_head_len = struct.unpack('i', bin_head)[0] # unpack 获取报文头长度
head_json = client.recv(json_head_len).decode() # 解码 获得 json格式的 报头字典
dic_head = json.loads(head_json) # 反序列化,得到 data的长度所在的字典
size = dic_head.get('data_size') # 取到data的真实长度值
length = 0
bin_toatal = b'' while length < size:
bin_content = client.recv(500)
bin_toatal += bin_content
length += len(bin_content) # 此处要累加bin_content的长度
print('当前下载进度',size , length , length / size)
print('当前下载进度---------------->', length / size) print(bin_toatal.decode('gbk'))
except Exception as e:
print(e)
break client.close()
服务端模板:
# _*_ coding: gbk _*_
# @Author: Wonder
import socket
import subprocess
import json
import struct server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('172.16.10.180', 9527))
server.listen(3)
while True:
conn, addr = server.accept()
while True:
try: bin_head = conn.recv(4) # 获取4位长度的报文头
json_head = struct.unpack('i', bin_head)[0] # 获得报头长度--->int bin_head = conn.recv(json_head).decode('utf-8') # 获取报头信息 ------>binary----->JSON
dic_head = json.loads(bin_head) # 反序列化得到字典
size = dic_head.get('data_size') # 字典取值得到数据长度 length = 0
bin_toatal = b''
while length < size: # if 循环接收,直到长度和报头中的长度一致
bin_content = conn.recv(50)
bin_toatal += bin_content
length += len(bin_toatal) cmd = bin_toatal.decode('utf-8') subprocess_obj = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = subprocess_obj.stdout.read() # binary
stderr = subprocess_obj.stderr.read() back_data_len = len(stderr) + len(stdout)
print(back_data_len) server_dict = {
'data_size': back_data_len # 务必代表二进制的长度
}
back_json = json.dumps(server_dict).encode('utf-8') # 序列化成 json字典 ------->json----->binary
server_head = struct.pack('i', len(back_json)) # 转成4位长度的二进制, 表示报头长度
conn.send(server_head) # 发报头长度
conn.send(back_json) # 发报头
conn.send(stdout) # 发数据
conn.send(stderr) except Exception as e:
print(e)
break
conn.close()
server.close()
UDP的初级使用
UDP服务端(即时通讯,你一句我一句)
# _*_ coding: gbk _*_
# @Author: Wonder
import socket # 指定是 数据报,type= 一定要写,不然报错
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(
('127.0.0.1', 9527)
) while True:
data, addr = sk.recvfrom(1024)
print(data.decode('utf-8'))
sk.sendto('永不在线'.encode('UTF-8'), addr)
客户端要绑定, 接收是recvfrom ,接收的是data和addr ,发送是sendto,发送的是data和目标addr
UDP客户端
# _*_ coding: gbk _*_
# @Author: Wonder
import socket sk = socket.socket(type=socket.SOCK_DGRAM)
addr = ('127.0.0.1', 9527)
while True:
msg = input('>>>输入内容')
if msg == 'q':
break
sk.sendto(msg.encode('utf-8'), addr)
data, back = sk.recvfrom(1024)
print(data.decode('utf-8'))
CSIC_716_20191205【TCP-解决粘包问题、UDP模板】的更多相关文章
- tcp粘包,udp丢包
TCP是面向流的, 流, 要说明就像河水一样, 只要有水, 就会一直流向低处, 不会间断. TCP为了提高传输效率, 发送数据的时候, 并不是直接发送数据到网路, 而是先暂存到系统缓冲, 超过时间或者 ...
- TCP通信粘包问题分析和解决
转载至https://www.cnblogs.com/kex1n/p/6502002.html 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发 ...
- TCP粘包, UDP丢包, nagle算法
一.TCP粘包 1. 什么时候考虑粘包 如果利用tcp每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题(因为只有一种包结构,类似于http协议,UDP不会出 ...
- TCP通信粘包问题分析和解决(全)(转)
TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...
- tcp粘包、解决粘包问题
目录 subproess模块 TCP粘包问题 粘包两种情况 解决粘包问题 struct模块的使用 使用struct模块解决粘包 优化解决粘包问题 上传大文件 服务端 客户端 UDP协议 upd套接字 ...
- 8-2udp和tcp网络编程以及粘包和解决粘包的方法
一 tcp网络编程 server 端 import socket sk=socket.socket() #实例化一个对象 sk.setsockopt(socket.SOL_SOCKET,socket ...
- tcp的粘包和拆包示例以及使用LengthFieldFrameDecoder来解决的方法
粘包和拆包是什么? TCP协议是一种字节流协议,没有记录边界,我们在接收消息的时候,不能人为接收到的数据包就是一个整包消息 当客户端向服务器端发送多个消息数据的时候,TCP协议可能将多个消息数据合并成 ...
- day31——recv工作原理、高大上版解决粘包方式、基于UDP协议的socket通信
day31 recv工作原理 源码解释: Receive up to buffersize bytes from the socket. 接收来自socket缓冲区的字节数据, For the opt ...
- TCP粘包问题的解决方案02——利用readline函数解决粘包问题
主要内容: 1.read,write 与 recv,send函数. recv函数只能用于套接口IO ssize_t recv(int sockfd,void * buff,size_t len,i ...
- 《精通并发与Netty》学习笔记(14 - 解决TCP粘包拆包(二)Netty自定义协议解决粘包拆包)
一.Netty粘包和拆包解决方案 Netty提供了多个解码器,可以进行分包的操作,分别是: * LineBasedFrameDecoder (换行) LineBasedFrameDecoder是回 ...
随机推荐
- 寻找链表倒数第k个元素,只遍历一遍(编程之美)
class LNode { public LNode next; public int data; } /*找出倒数第k个元素,只遍历一遍*/ class Kk { private static LN ...
- MyEclipse中android 项目如何解决第三方jar无法关联源码的问题( The JAR of this class file belongs to container 'Android Private Libraries' which does not allow modifications to source attachments on its entries.)
若我们要为第三方jar(android-support-v4.jar)关联源码通常的做法是 右键项目 单击菜单Properties 单击菜单 Java Build Path 单击 Libraries ...
- 使用Turbine对集群进行监控
为什么要使用Turbine Turbine是聚合服务器发送事件流数据的一个工具,hystrix的监控中,只能监控单个节点,实际生产中都为集群,因此可以通过turbine来监控集群下hystrix的me ...
- slect fd_set
select()机制中提供一fd_set的数据结构,实际上是一long类型的数组,每一个数组元素都能与一打开的文件句柄(不管是socket句柄,还是其他文件或命名管道或设备句柄)建立联系,建立联系的工 ...
- linux配置java环境变量(详细)(转)
linux配置java环境变量(详细) 一. 解压安装jdk 在shell终端下进入jdk-6u14-linux-i586.bin文件所在目录, 执行命令 ./jdk-6u14-linux-i586. ...
- 【LeetCode】拓扑排序
[207] Course Schedule 排课问题,n门课排课,有的课程必须在另外一些课程之前上,问能不能排出来顺序. 题解:裸的拓扑排序.参考代码见算法竞赛入门指南这本书. class Solut ...
- js正则删除字符串中的部分内容
// 例如 let a = `(ID)444` a.replace(/\(ID\)/ig, '') // 结果 "444"
- leetcode-161周赛-5248-统计【优美子数组】
题目描述: 自己的提交:超时: class Solution: def numberOfSubarrays(self, nums, k: int) -> int: dp = [0]* (len( ...
- C# 16进制转字符串,字符串转16进制
{ //========================================================== //16进制转字符串 public static byte[] HexTo ...
- 基于SpringBoot的花里胡哨配置
花里胡哨的配置 记录一下流行框架的一些常用配置 lomback配置文件 <?xml version="1.0" encoding="UTF-8"?> ...