当前位置: 首页 > news >正文

网站站内优化个人博客大全

网站站内优化,个人博客大全,网站关键词是什么,建网站所需材料tcp粘包原理和解决 ​ 咱们先通过展示基于tcp 的cs端消息通信时的现象#xff0c;带着问题再解释下面的tcp粘包问题。 一、原始代码 tcp 服务端代码 // socket_stick/server/main.gofunc process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)var bu…tcp粘包原理和解决 ​ 咱们先通过展示基于tcp 的cs端消息通信时的现象带着问题再解释下面的tcp粘包问题。 一、原始代码 tcp 服务端代码 // socket_stick/server/main.gofunc process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)var buf [1024]bytefor {n, err : reader.Read(buf[:])if err io.EOF {break}if err ! nil {fmt.Println(read from client failed, err:, err)break}recvStr : string(buf[:n])fmt.Println(收到client发来的数据, recvStr)} }func main() {listen, err : net.Listen(tcp, 127.0.0.1:30000)if err ! nil {fmt.Println(listen failed, err:, err)return}defer listen.Close()for {conn, err : listen.Accept()if err ! nil {fmt.Println(accept failed, err:, err)continue}go process(conn)} }tcp客户端代码 // socket_stick/client/main.gofunc main() {conn, err : net.Dial(tcp, 127.0.0.1:30000)if err ! nil {fmt.Println(dial failed, err, err)return}defer conn.Close()for i : 0; i 20; i {msg : Hello, Hello. How are you?conn.Write([]byte(msg))} }执行后服务端输出如下客户端分10次发送的数据在服务端并没有成功的输出10次而是多条数据“粘”到了一起… 收到client发来的数据 Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you? 二、粘包解析 1.为什么会出现TCP粘包问题 TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包从接收缓冲区来看后一包数据的头紧接着前一包数据的尾出现粘包的原因是多方面的可能是来自发送方也可能是来自接收方。 在socket网络编程中都是端到端通信由客户端端口服务端端口客户端IP服务端IP传输协议组成的五元组可以明确的标识一条连接。在TCP的socket编程中发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包更加高效的的发给接收端于是采用了优化算法Nagle算法将多次间隔较小、数据量较小的数据合并成一个数据量大的数据块然后进行封包。那么这样一来接收端就必须使用高效科学的拆包机制来分辨这些数据。 2.造成TCP粘包原因 1.由Nagle算法造成的发送端的粘包Nagle算法是一种改善网络传输效率的算法。简单来说就是当我们提交一段数据给TCP发送时TCP并不立刻发送此段数据而是等待一小段时间看看在等待期间是否还有要发送的数据若有则会一次把这两段数据发送出去。 2.接收端接收不及时造成的接收端粘包TCP会把接收到的数据存在自己的缓冲区中然后通知应用层取数据。当应用层由于某些原因不能及时的把TCP的数据取出来就会造成TCP缓冲区中存放了几段数据。 3.什么时候需要处理粘包问题 如果发送方发送的多组数据本来就是同一块数据的不同部分比如说一个文件被分成多个部分发送这时当然不需要处理粘包现象如果多个分组毫不相干甚至是并列关系那么这个时候就一定要处理粘包现象了 4.如何处理粘包问题 1发送方 对于发送方造成的粘包问题可以通过关闭Nagle算法来解决使用TCP_NODELAY选项来关闭算法。 2接收方 接收方没有办法来处理粘包现象只能将问题交给应用层来处理。 2应用层 应用层的解决办法简单可行不仅能解决接收方的粘包问题还可以解决发送方的粘包问题。 解决办法循环处理应用程序从接收缓存中读取分组时读完一条数据就应该循环读取下一条数据直到所有数据都被处理完成但是如何判断每条数据的长度呢 格式化数据每条数据有固定的格式开始符结束符这种方法简单易行但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。发送长度发送每条数据时将数据的长度一并发送例如规定数据的前4位是数据的长度应用层在处理时可以根据长度来判断每个分组的开始和结束位置。 5.UDP会不会产生粘包问题 TCP为了保证可靠传输并减少额外的开销每次发包都要验证采用了基于流的传输基于流的传输不认为消息是一条一条的是无保护消息边界的保护消息边界指传输协议把数据当做一条独立的消息在网上传输接收端一次只能接受一条独立的消息。 UDP则是面向消息传输的是有保护消息边界的接收方一次只接受一条独立的信息所以不存在粘包问题。 举个例子有三个数据包大小分别为2k、4k、6k如果采用UDP发送的话不管接受方的接收缓存有多大我们必须要进行至少三次以上的发送才能把数据包发送完但是使用TCP协议发送的话我们只需要接受方的接收缓存有12k的大小就可以一次把这3个数据包全部发送完毕。 三、改进代码 解决思路更改发送方可控性不高所以需要在应用侧入手而且不更改协议继续基于tcp实现。 出现”粘包”的关键在于接收方不确定将要传输的数据包的大小因此我们可以对数据包进行封包和拆包的操作。 封包封包就是给一段数据加上包头这样一来数据包就分为包头和包体两部分内容了(过滤非法包时封包会加入”包尾”内容)。包头部分的长度是固定的并且它存储了包体的长度根据包头长度固定以及包头中含有包体长度的变量就能正确的拆分出一个完整的数据包。 我们可以自己定义一个协议比如数据包的前4个字节为包头里面存储的是发送的数据的长度。 // socket_stick/proto/proto.go package protoimport (bufiobytesencoding/binary )// Encode 将消息编码 func Encode(message string) ([]byte, error) {// 读取消息的长度转换成int32类型占4个字节var length int32(len(message))var pkg new(bytes.Buffer)// 写入消息头err : binary.Write(pkg, binary.LittleEndian, length)if err ! nil {return nil, err}// 写入消息实体err binary.Write(pkg, binary.LittleEndian, []byte(message))if err ! nil {return nil, err}return pkg.Bytes(), nil }// Decode 解码消息 func Decode(reader *bufio.Reader) (string, error) {// 读取消息的长度lengthByte, _ : reader.Peek(4) // 读取前4个字节的数据lengthBuff : bytes.NewBuffer(lengthByte)var length int32err : binary.Read(lengthBuff, binary.LittleEndian, length)if err ! nil {return , err}// Buffered返回缓冲中现有的可读取的字节数。if int32(reader.Buffered()) length4 {return , err}// 读取真正的消息数据pack : make([]byte, int(4length))_, err reader.Read(pack)if err ! nil {return , err}return string(pack[4:]), nil }tcp 服务端使用decode解码消息 // socket_stick/server2/main.gofunc process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)for {msg, err : proto.Decode(reader)if err io.EOF {return}if err ! nil {fmt.Println(decode msg failed, err:, err)return}fmt.Println(收到client发来的数据, msg)} }func main() {listen, err : net.Listen(tcp, 127.0.0.1:30000)if err ! nil {fmt.Println(listen failed, err:, err)return}defer listen.Close()for {conn, err : listen.Accept()if err ! nil {fmt.Println(accept failed, err:, err)continue}go process(conn)} }tcp 客户端使用encode编码消息 // socket_stick/client2/main.gofunc main() {conn, err : net.Dial(tcp, 127.0.0.1:30000)if err ! nil {fmt.Println(dial failed, err, err)return}defer conn.Close()for i : 0; i 20; i {msg : Hello, Hello. How are you?data, err : proto.Encode(msg)if err ! nil {fmt.Println(encode msg failed, err:, err)return}conn.Write(data)} }改进后发包效果 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you? 收到client发来的数据 Hello, Hello. How are you?
http://www.ho-use.cn/article/10816608.html

相关文章:

  • 做网站互联网公司排名网络美工是干啥的
  • 中国代理网官方网站义乌门户网站建设
  • 网站版面布局结构怎么做微课网站
  • 做网站需要宽带销售管理软件排行
  • 音乐网站答辩可以做蛋白三位结构图的网站
  • 网站建设后怎么手机网页制作html
  • 电商网站开发的主流技术wordpress 修改小部件
  • 手机端网站建设郑州网站开发工具 哪个好
  • 下面有关网络营销特点的论述正确的有宁波自适应网站建设优化建站
  • 网站技术报务费如何做会计分录网站开发技术服务费合同范本
  • 网站收录下降的原因做网站合同
  • 门户网站是什么jsp网站 值班功能
  • 陕西省城乡住房建设部网站网站推广方式百度云
  • e龙岩网站建设网站有哪些
  • 微信手机网站搭建网站建设的一些知识
  • 珠海酒店网站建设公司建个网站需要多少钱
  • asp评价网站开发文档开发app需要多少资金
  • 怎么看一个网站用什么做的微信名字制作软件小程序
  • 网站便宜建设网站代运营
  • 网站模版建设网站开发设计图片
  • 网站设计详细设计dede网站不能运行php文件
  • 菏泽市建设局网站电话东营市房产信息网
  • 供求网站建设网站代理工具
  • 有谁知道知乎网站是谁做的以春天为主题的网站建设资源
  • 平舆专业网站建设网站开发周期
  • 网站更新方法值得信赖网页制作平台
  • 企业网站功能对比分析外发加工单表格模板
  • 商品网站策划书wordpress 亲子模板下载
  • 网站建设借鉴贵阳建设厅网站
  • 网站建立的做定制校服的网站