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数据的封装


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数据的封装的主要内容,如果未能解决你的问题,请参考以下文章

Python Socket编程

socket

3 Socket介绍

Socket入门

什么是socket

Socket编程入门