8月5日 TCP与UDP协议,socket套接字编程 与TCP黏包问题及解决思路
-
TCP与UDP协议
-
socket套接字编程
-
TCP黏包问题及解决思路
TCP与UDP协议
1.TCP协议的三次握手和四次挥手:
三次握手其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。
第一次握手是由客户端向服务器发送的syn=1数据包标志着客户端想要和服务器建立连接。
第二次握手是服务器在接收到客户端的syn返回ack=n+1标志着连接已经确认并且一个数据包被接收了,到底是对哪个数据包的确认,数据包的序列号信息存储在ack字段中
在确认后 服务器也会向客户端发送syn=2的数据包和客户端来建立联系
第三次握手客户端收到服务器的syn数据包后,会发送ack=n+2数据包来应答标志着连接已经确认。
2.UDP协议
UDP是基于IP的简单协议,不可靠的协议。
UDP的优点:简单,轻量化。
UDP的缺点:没有流程控制,没有应答确认机制,不能解决丢包、重发、错序问题。
socket套接字
基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
基于网络类型的套接字家族
套接字家族的名字:AF_INET
服务端代码:
"""运行程序的时候 肯定是先确保服务端运行 之后才是客户端""" import socket # 1.创建一个socket对象 server = socket.socket() # 括号内什么都不写 默认就是基于网络的TCP套接字 # 2.绑定一个固定的地址(ip\port) server.bind(('127.0.0.1', 8080)) # 127.0.0.1本地回环地址(只允许自己的机器访问) # 3.半连接池(暂且忽略) server.listen(5) # 4.开业 等待接客 sock, address = server.accept() print(sock, address) # sock是双向通道 address是客户端地址 # 5.数据交互 sock.send(b'hello big baby~') # 朝客户端发送数据 data = sock.recv(1024) # 接收客户端发送的数据 1024bytes print(data) # 6.断开连接 sock.close() # 断链接 server.close() # 关机
客户端代码:
import socket # 1.产生一个socket对象 client = socket.socket() # 2.连接服务端(拼接服务端的ip和port) client.connect(('127.0.0.1', 8080)) # 3.数据交互 data = client.recv(1024) # 接收服务端发送的数据 print(data) client.send(b'hello sweet server') # 朝服务端发送数据 # 4.关闭 client.close()
"""代码优化: 1.send与recv 客户端与服务端不能同时执行同一个 有一个收 另外一个就是发 有一个发 另外一个就是收 不能同时收或者发!!! 2.消息自定义 input获取用户数据即可(主要编码解码) 3.循环通信 给数据交互环节添加循环即可 4.服务端能够持续提供服务 不会因为客户端断开连接而报错 异常捕获 一旦客户端断开连接 服务端结束通信循环 调到连接处等待 5.消息不能为空 判断是否为空 如果是则重新输入(主要针对客户端)"""
TCP黏包问题及解决思路
1.黏包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的
从发送端来看由于TCP协议本身的机制客户端与服务器会维持一个连接,数据在连接不断开的情况下,可以持续不断地将多个数据包发往服务器,但是如果发送的网络数据包太小并且时间间隔很多 那么就会自动组织到一起
从接受端来看服务器在接收到数据库后,放到缓冲区中,如果消息没有被及时从缓存区取走,下次在取数据的时候可能就会出现一次取出多个数据包的情况,造成黏包现象
2.如何解决
解决黏包问题我问可以用struct模块来解决
服务端代码:
info = '下午上课 以后可能是常态!' print(len(info)) # 13 数据原本的长度 res = struct.pack('i', len(info)) # 将数据原本的长度打包 print(len(res)) # 4 打包之后的长度是4 ret = struct.unpack('i', res) # 将打包之后固定长度为4的数据拆包 print(ret[0]) # 13 又得到了原本数据的长度
客户端代码:
info1 = '打起精神啊 下午也需要奋斗 也需要认真听 克服困难 你困我也困!!!' print(len(info1)) # 34 res = struct.pack('i', len(info1)) # 将数据原本的长度打包 print(len(res)) # 4 打包之后的长度是4 ret = struct.unpack('i', res) print(ret[0]) # 34
struct模块无论数据长度是多少 都可以帮你打包成固定长度,然后基于该固定长度 还可以反向解析出真实长度
思路
1.先将真实数据的长度制作成固定长度 4
2.先发送固定长度的报头
3.再发送真实数据
1.先接收固定长度的报头 4
2.再根据报头解压出真实长度
3.根据真实长度接收即可
struct模块针对数据量特别大的数字没有办法打包!!!
原文地址:https://www.cnblogs.com/tai-yang77/p/16555682.html
- ERROR 1396 (HY000): Operation CREATE USER faile...
- hive安装后测试
- 【算法】论平衡二叉树(AVL)的正确种植方法
- 【JavaScript】 JS面向对象的模式与实践
- log4j:ERROR Failed to load driver
- 前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例
- 前端MVC Vue2学习总结(六)——axios与跨域HTTP请求、Lodash工具库
- spring之config.xml完整版示例
- 前端MVC Vue2学习总结(五)——表单输入绑定、组件
- 【HCTF】2017部分Web出题思路详解
- 前端MVC Vue2学习总结(四)——条件渲染、列表渲染、事件处理器
- 如何移除Android应用广告
- 前端MVC Vue2学习总结(三)——模板语法、过滤器、计算属性、观察者、Class 与 Style 绑定
- 前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Kubernetes 问题定位技巧:分析 ExitCode
- 从零单排学Redis【铂金一】
- 理解JavaScript中的浮点数
- linux每日命令(32):gzip命令
- Vue.js 入门1 安装
- UIScrollView嵌套的完美解决方案
- RocketMQ 命令行工具源码结构解析
- Docker学习之宿机容器时区同步
- MySQL分组统计与多表联合查询的基本知识归纳总结
- Python数据处理从零开始----第四章(可视化)①②堆积柱状图目录使用Matplotlib和Pandas轻松堆积图表
- Centos6.5安装配置mongodb
- Ubuntu 安装后的配置及美化(一)
- 数据同步中的动态调度
- BZOJ5068: 友好的生物(状压 贪心)
- 使用Python实现子区域数据分类统计