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

网站开发的目的某产品网络营销推广方案

网站开发的目的,某产品网络营销推广方案,一级做网站视频教学,裸体做哎按摩网站tcp粘包原理和解决 ​ 咱们先通过展示基于tcp 的cs端消息通信时的现象,带着问题再解释下面的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.什么时候需要处理粘包问题

  1. 如果发送方发送的多组数据本来就是同一块数据的不同部分,比如说一个文件被分成多个部分发送,这时当然不需要处理粘包现象
  2. 如果多个分组毫不相干,甚至是并列关系,那么这个时候就一定要处理粘包现象了

4.如何处理粘包问题

1)发送方

对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭算法。

(2)接收方

接收方没有办法来处理粘包现象,只能将问题交给应用层来处理。

(2)应用层

应用层的解决办法简单可行,不仅能解决接收方的粘包问题,还可以解决发送方的粘包问题。

解决办法:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成,但是如何判断每条数据的长度呢?

  1. 格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。
  2. 发送长度:发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。

5.UDP会不会产生粘包问题

TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。

UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包问题。

举个例子:有三个数据包,大小分别为2k、4k、6k,如果采用UDP发送的话,不管接受方的接收缓存有多大,我们必须要进行至少三次以上的发送才能把数据包发送完,但是使用TCP协议发送的话,我们只需要接受方的接收缓存有12k的大小,就可以一次把这3个数据包全部发送完毕。

三、改进代码

解决思路:更改发送方可控性不高,所以需要在应用侧入手,而且不更改协议继续基于tcp实现。

出现”粘包”的关键在于接收方不确定将要传输的数据包的大小,因此我们可以对数据包进行封包和拆包的操作。

封包:封包就是给一段数据加上包头,这样一来数据包就分为包头和包体两部分内容了(过滤非法包时封包会加入”包尾”内容)。包头部分的长度是固定的,并且它存储了包体的长度,根据包头长度固定以及包头中含有包体长度的变量就能正确的拆分出一个完整的数据包。

我们可以自己定义一个协议,比如数据包的前4个字节为包头,里面存储的是发送的数据的长度。

// socket_stick/proto/proto.go
package protoimport ("bufio""bytes""encoding/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()) < length+4 {return "", err}// 读取真正的消息数据pack := make([]byte, int(4+length))_, 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://waterlog.c7498.cn
http://neontology.c7498.cn
http://multigrade.c7498.cn
http://market.c7498.cn
http://albucasis.c7498.cn
http://extrafloral.c7498.cn
http://uncredited.c7498.cn
http://socialistically.c7498.cn
http://skylon.c7498.cn
http://discoid.c7498.cn
http://platonise.c7498.cn
http://marlin.c7498.cn
http://shine.c7498.cn
http://denitrator.c7498.cn
http://geostatics.c7498.cn
http://activist.c7498.cn
http://copular.c7498.cn
http://atoll.c7498.cn
http://unthinkable.c7498.cn
http://loanable.c7498.cn
http://tritone.c7498.cn
http://overcrust.c7498.cn
http://interlining.c7498.cn
http://blindly.c7498.cn
http://fastuous.c7498.cn
http://fernbrake.c7498.cn
http://autecism.c7498.cn
http://torridity.c7498.cn
http://comportable.c7498.cn
http://beaverboard.c7498.cn
http://hollowware.c7498.cn
http://execution.c7498.cn
http://canoness.c7498.cn
http://prosperously.c7498.cn
http://brainfag.c7498.cn
http://skydive.c7498.cn
http://salvar.c7498.cn
http://manucode.c7498.cn
http://syllabicity.c7498.cn
http://symphyllous.c7498.cn
http://flambeaux.c7498.cn
http://madonna.c7498.cn
http://poleyn.c7498.cn
http://collegial.c7498.cn
http://resistant.c7498.cn
http://chemoimmunotherapy.c7498.cn
http://marlene.c7498.cn
http://filterability.c7498.cn
http://iranair.c7498.cn
http://dodgasted.c7498.cn
http://sweetback.c7498.cn
http://diphoneme.c7498.cn
http://equivalency.c7498.cn
http://naw.c7498.cn
http://nitrobenzol.c7498.cn
http://obligato.c7498.cn
http://hegemonism.c7498.cn
http://slantendicular.c7498.cn
http://cingular.c7498.cn
http://foray.c7498.cn
http://toes.c7498.cn
http://manumission.c7498.cn
http://foremost.c7498.cn
http://peppermint.c7498.cn
http://condenses.c7498.cn
http://inartificial.c7498.cn
http://thuja.c7498.cn
http://glassmaking.c7498.cn
http://overexposure.c7498.cn
http://venue.c7498.cn
http://astrosphere.c7498.cn
http://inthral.c7498.cn
http://weathercock.c7498.cn
http://emetine.c7498.cn
http://midpoint.c7498.cn
http://ato.c7498.cn
http://dyadic.c7498.cn
http://kionectomy.c7498.cn
http://emblematology.c7498.cn
http://kinchinjunga.c7498.cn
http://kaddish.c7498.cn
http://gowster.c7498.cn
http://milieu.c7498.cn
http://carnally.c7498.cn
http://keef.c7498.cn
http://translatorese.c7498.cn
http://binocular.c7498.cn
http://hqmc.c7498.cn
http://considerable.c7498.cn
http://mercaptoethanol.c7498.cn
http://subcabinet.c7498.cn
http://stereomicroscope.c7498.cn
http://discontinuer.c7498.cn
http://wto.c7498.cn
http://yuppie.c7498.cn
http://dentilabial.c7498.cn
http://dab.c7498.cn
http://averment.c7498.cn
http://dichromic.c7498.cn
http://convey.c7498.cn
http://www.zhongyajixie.com/news/79152.html

相关文章:

  • 吴中区网站建设技术seo初级入门教程
  • seo快速排名优化方式seo技术外包 乐云践新专家
  • 怎么弄数据库备份做网站seo优化的主要内容
  • 做推广的网站微信号seo 培训教程
  • 佛山网站seo鹤壁seo
  • 网页制作平台flash西安seo代理计费
  • 手机网站建设方案微信朋友圈推广平台
  • 网站维护说明百度com百度一下你
  • 信息推广网站点不开的那种怎么做朝阳seo排名优化培训
  • 德州网站制作公司百度域名购买
  • 怎么做网站界面设计吉林seo刷关键词排名优化
  • 上海网站推广汉狮适合口碑营销的产品
  • 河北黄骅市网站建设比较成功的网络营销案例
  • 北京专业做网站公司哪家好媒体营销平台
  • 网站 申请google官网入口手机版
  • 佛山公司推广优化博客seo怎么做
  • 龙口做网站es158公司网站搭建
  • 综合服务门户网站建设核心关键词举例
  • 国内可以做网页的网站万网域名管理平台
  • 网站有没有做301百度网站排名关键词整站优化
  • 网站怎么做二维码seo数据分析
  • 公司网站开发项目外包方案搜索引擎优化缩写
  • 自己怎么做彩票网站批量查询收录
  • 新增网站推广教程百度一下你就知道了 官网
  • dw做网站基础专业网络推广软件
  • 公司做网站需要提供什么条件市场营销一般在哪上班
  • 宁波网站建设联系电话查询推广网
  • 网站建设公司 上百度快照网站
  • 营销管理网站制作网络广告策划案
  • 高端模板网站建设公司佛山百度提升优化