golang 自定义封包协议(转的)
- package protocol
- import (
- "bytes"
- "encoding/binary"
- )
- const (
- ConstHeader = "jackluo"
- ConstHeaderLength = 7
- ConstSaveDataLength = 4
- )
- //封包
- func Packet(message []byte) []byte {
- return append(append([]byte(ConstHeader), IntToBytes(len(message))...), message...)
- }
- //解包
- func Unpack(buffer []byte, readerChannel chan []byte) []byte {
- length := len(buffer)
- var i int
- for i = 0; i < length; i = i + 1 {
- if length < i+ConstHeaderLength+ConstSaveDataLength {
- break
- }
- if string(buffer[i:i+ConstHeaderLength]) == ConstHeader {
- messageLength := BytesToInt(buffer[i+ConstHeaderLength : i+ConstHeaderLength+ConstSaveDataLength])
- if length < i+ConstHeaderLength+ConstSaveDataLength+messageLength {
- break
- }
- data := buffer[i+ConstHeaderLength+ConstSaveDataLength : i+ConstHeaderLength+ConstSaveDataLength+messageLength]
- readerChannel <- data
- i += ConstHeaderLength + ConstSaveDataLength + messageLength - 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)
- }
- package main
- import (
- "fmt"
- "net"
- "os"
- "./protocol"
- )
- func main() {
- netListen, err := net.Listen("tcp", ":9988")
- CheckError(err)
- defer netListen.Close()
- Log("Waiting for clients")
- for {
- conn, err := netListen.Accept()
- if err != nil {
- continue
- }
- Log(conn.RemoteAddr().String(), " tcp connect success")
- go handleConnection(conn)
- }
- }
- func handleConnection(conn net.Conn) {
- //声明一个临时缓冲区,用来存储被截断的数据
- tmpBuffer := make([]byte, 0)
- //声明一个管道用于接收解包的数据
- readerChannel := make(chan []byte, 16)
- go reader(readerChannel)
- buffer := make([]byte, 1024)
- for {
- n, err := conn.Read(buffer)
- if err != nil {
- Log(conn.RemoteAddr().String(), " connection error: ", err)
- return
- }
- /* Log(conn.RemoteAddr().String(), "receive data length:", n)
- Log(conn.RemoteAddr().String(), "receive data:", buffer[:n])
- Log(conn.RemoteAddr().String(), "receive data string:", string(buffer[:n]))
- */
- tmpBuffer = protocol.Unpack(append(tmpBuffer, buffer[:n]...), readerChannel)
- }
- }
- func reader(readerChannel chan []byte) {
- for {
- select {
- case data := <-readerChannel:
- Log(string(data))
- }
- }
- }
- func Log(v ...interface{}) {
- fmt.Println(v...)
- }
- func CheckError(err error) {
- if err != nil {
- fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
- os.Exit(1)
- }
- }
- package main
- import (
- "fmt"
- "net"
- "os"
- "time"
- "./protocol"
- )
- func sender(conn net.Conn) {
- for i := 0; i < 100; i++ {
- words := "{\"Id\":1,\"Name\":\"golang\",\"Message\":\"message\"}"
- conn.Write(protocol.Packet([]byte(words)))
- }
- fmt.Println("send over")
- }
- func main() {
- server := "127.0.0.1:9988"
- tcpAddr, err := net.ResolveTCPAddr("tcp4", server)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
- os.Exit(1)
- }
- conn, err := net.DialTCP("tcp", nil, tcpAddr)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
- os.Exit(1)
- }
- defer conn.Close()
- fmt.Println("connect success")
- go sender(conn)
- for {
- time.Sleep(1 * 1e9)
- }
- }
golang 自定义封包协议(转的)的更多相关文章
- Newtonsoft.Json 自定义 解析协议
在开发web api的时候 遇到一个要把string未赋值默认为null的情况改成默认为空字符串的需求 这种情况就需要自定义json序列话的 解析协议了 Newtonsoft.Json默认的解析协议是 ...
- 【Win 10开发】协议-上篇:自定义应用协议
就像系统许多内置应用可以通过URI来启动(如ms-settings-bluetooth:可以打开蓝牙设置页),我们自己开发的应用程序,如果需要的话,可以为应用程序自定义一个协议.应用程序协议在安装时会 ...
- TeamTalk自定义IM协议的理解
一.TeamTalk自定义IM协议 TeamTalk自定义IM协议是一种基于protocol buffer的消息传递协议,protocol buffer可以自定义消息格式.protocol buffe ...
- golang 自定义importpath
golang 的包导入和其他语言有好多不一样的地方,以下是一个自定义的导入 golang 自定义导入说明 一个官方的说明 比较简单,就不翻译了,主要是说我们可以通过添加meta 数据告诉包如何进行加载 ...
- [转]Windows 注册自定义的协议
[转自] http://blog.sina.com.cn/s/blog_86e4a51c01010nik.html 1.注册应用程序来处理自定义协议 你必须添加一个新的key以及相关的value到HK ...
- 自定义URL协议在Web中启动本地应用程序
转自(http://blog.csdn.net/jackychen_king/article/details/7743811) 1.注册应用程序来处理自定义协议 你必须添加一个新的key以及相关的va ...
- mac下自定义伪协议配置
之前查了很多资料,最近也在挖掘研究这方面的漏洞. windows的很简单,在注册表配置就好了,但是mac os 是unix的,没有注册表这么一说. 但是发现腾讯等配置了自定义等协议,例如:tencen ...
- netty5自定义私有协议实例
一般业务需求都会自行定义私有协议来满足自己的业务场景,私有协议也可以解决粘包和拆包问题,比如客户端发送数据时携带数据包长度,服务端接收数据后解析消息体,获取数据包长度值,据此继续获取数据包内容.我们来 ...
- 基于Netty的RPC架构学习笔记(九):自定义序列化协议
文章目录 为什么需要自定义序列化协议
随机推荐
- flume-ng 集群搭脚本
#!/bin/bash # author: xirong # date : -- ##### 搭建 flume 集群的脚本 # 注意: # . 需要 jdk7 环境,如果没有 Java 环境,请配置 ...
- Oracle 备份与恢复介绍
一.Oracle备份方式分类:Oracle有两类备份方式:(1)物理备份:是将实际组成数据库的操作系统文件从一处拷贝到另一处的备份过程,通常是从磁盘到磁带.物理备份又分为冷备份.热备份: (2)逻 ...
- android 入门-安装环境
1.安装jdk 相关链接 2.安装adt 里面包含eclipse 3.下载androidsdk 4.打开eclipse 找到windows -> 属性 -> android 主目录 复制 ...
- 信号量互斥,王明学learn
信号量互斥 信号量(又名:信号灯)与其他进程间通信方式不大相同,主要用途是保护临界资源(进程互斥).进程可以根据它判定是否能够访问某些共享资源.除了用于访问控制外,还可用于进程同步. 一.信号量分类 ...
- 如何控制Java中的线程,总结了3种方法...
问题:利用Java多线程,轮流打印数字,也就是怎么控制线程.... 1:通过synchronized的关键字,对类的static final 成员进行Lock,锁住对象,来实现同步. private ...
- socket编程学习
socket: 也称作套接字,应用程序通常通过套接字向网络发出请求或者应答网络请求. 常用的套接字API函数: 1.socket(): 函数原型为:int socket(int domain, int ...
- JAVA Day3
分支与循环 char sex = in.next().charAt(0); java中 ...
- .NET运用AJAX 总结及其实例
1.AJAX简介 (1.没有AJAX会怎么样?普通的ASP.Net每次执行服务端方法的时候都要刷新当前页面,比如实现显示服务器的时间.每次都要刷新页面的坏处:页面刷新打断用户操作.速度慢.增加服务器的 ...
- Android性能优化之布局优化
最新最准确内容建议直接访问原文:Android性能优化之布局优化 本文为Android性能优化的第二篇——布局优化,主要介绍使用抽象布局标签(include, viewstub, merge).去除不 ...
- 07 JavaWeb
软件开发的两种架构:c/s和b/s * C/S client/server 客户端/服务器 例子:QQ 快播 暴风影音... ...