socket数据的封装
Posted Golang语言社区
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket数据的封装相关的知识,希望对你有一定的参考价值。
什么是socket?
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
socket与http的区别
在网络七层架构中,http属于应用层协议,如图:图
而socket是位于应用层和传输层之间的一个抽象层,是本来不存在与七层架构中的:图
socket通信流程是怎样进行的?
socket的通信流程:
流程解读:
1. server端创建socket
2. server端绑定socket和端口号
3. server端监听该端口号
4. server端启动accept()接收来自client端的连接请求,此时有连接进入时会往后续执行,没有链接则会阻塞在此
5. client端创建socket
6. client端根据server端的ip和port连接server端(tcp的三次握手)
7. 如果第6步连接成功,在server端将会收到一个连接,假如这个连接名叫conn
8. client端向server端发送数据
9. server端从conn中读取到client端发送过来的数据
10. 任何一端都可以主动断开连接
socket中传输数据出现的问题
粘包:当server端用一个buff接收数据,发现buff中除了一个完整的包之外还有其他的数据。
半包:server端未接收到一个完整的包,只接收到了一部分。
socket的封包与拆包
在实际开发中往往会封装自己的数据,一般分为Head和Body,Head中除了封装额外的信息之外,还会封装Body的长度在里面。这样就形成了如下数据:
Head{ //头信息 (总共占用6个字节)
One byte //第一个标志 (1个字节)
Two byte //第二个标志 (1个字节)
Length int32 //存放Body的数据长度 (4个字节)
}
Body{ //消息体 (总共占用?+4个字节)
Name []byte //名字 (占用?个字节)
Age int32 //年龄 (占用4个字节)
}
Data{
Head
Body
}
server端要对接收到的数据[]byte进行拆包以防止粘包和半包情况的发生。
注:Data这个数据结构在server端和client端都应保持一致
封包过程:
将一个封装好的Data数据转化成[]byte,然后发送。
拆包过程:
1. 循环从conn中读取数据,每次循环都判断接收到的数据是否>=6,若是,则表明接收完了Head,若否,继续执行下一次循环,知道满足条件
2. 接收完Head后,将前6个字节的数据解析到Data的Head中,对于从conn接收到的数据长度减去6(得到的是接收到的Body数据的长度),判断这个结果是否>=Head中Length,若否,循环继续接收数据;若是,则解析出Length长度的数据放入Data的Body,自此之后的数据又重新用一个Data来解析并存放
这样拆包就解决了粘包和半包的问题。
golang代码实现
简书贴代码真是蛋疼,截图算了
本文来自:简书
查看原文:socket数据的封装
以上是关于socket数据的封装的主要内容,如果未能解决你的问题,请参考以下文章