Golang 开发 Socket 通信时常用的 TCP 封包和解包协议
2023-02-18 16:39:47 时间
在开发 Socket 通信时,由于 TCP 协议的特性,在网络状况不佳的情况下,数据传输过程中经常会出现半包或粘包。为解决这一问题,通常我们需要自定义一个通信协议,增加一个 HEADER 部分,并在其中对数据包的长度进行声明,下面分享一段封包和解包的示例代码,可用于 Golang 开发 Socket 时处理数据传输,具体代码如下:
package protocol
import (
"bytes"
"encoding/binary"
)
const (
TCP_HEADER = "TCPHEADER"
TCP_HEADER_LEN = 9
TCP_DATA_LEN = 4
)
// 封包
func Enpack(msg []byte) []byte {
return append(append([]byte(TCP_HEADER), IntToBytes(len(msg))...), msg...)
}
// 解包
func Depack(buffer []byte, readerChannel chan []byte) []byte {
length := len(buffer)
var i int
for i = 0; i < length; i++ {
if length < i + TCP_HEADER_LEN + TCP_DATA_LEN {
break
}
if string(buffer[i:i + TCP_HEADER_LEN]) == TCP_HEADER {
msgLen := BytesToInt(buffer[i + TCP_HEADER_LEN : i + TCP_HEADER_LEN + TCP_DATA_LEN])
if length < i + TCP_HEADER_LEN + TCP_DATA_LEN + msgLen {
break
}
data := buffer[i + TCP_HEADER_LEN + TCP_DATA_LEN : i + TCP_HEADER_LEN + TCP_DATA_LEN + msgLen]
readerChannel <- data
i += TCP_HEADER_LEN + TCP_DATA_LEN + msgLen - 1
}
}
if i == length {
return make([]byte, 0)
}
return buffer[i:]
}
// 整形转换成字节
func IntToBytes(n int) []byte {
x := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, x)
return bytesBuffer.Bytes()
}
// 字节转换成整形
func BytesToInt(b []byte) int {
bytesBuffer := bytes.NewBuffer(b)
var x int32
binary.Read(bytesBuffer, binary.BigEndian, &x)
return int(x)
}
相关文章
- VS Code使用Git可视化管理源代码详细教程
- Visual Studio使用Git忽略不想上传到远程仓库的文件
- 使用git处理github中提交有冲突的pull request
- Linux CentOS7部署ASP.NET Core应用程序,并配置Nginx反向代理服务器和Supervisor守护服务
- Linux CentOS上安装 MySQL 8.0.16
- Linux系统彻底卸载MySQL数据库
- Git分布式版本控制器常用命令和使用
- Linux常用基本命令
- Linux安装Nginx二-基于源码编译安装
- Linux安装Nginx1-基于yum安装
- git commit 代码提交规范
- git status 查看状态文件名乱码
- MySQL server has gone away
- PHP 中的 final 关键字
- PHP 命令行指令
- PHP 代码复用机制 trait
- git stash 命令详解(保存开发进度)
- .git 目录结构内容解析
- linux 命令之查看文件内容
- git fetch 命令详解