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架构学习笔记(九):自定义序列化协议
文章目录 为什么需要自定义序列化协议
随机推荐
- wp8 入门到精通 Animation 背景加字体颜色从下向上变化颜色效果
<phone:PhoneApplicationPage.Resources> <Style x:Key="ButtonStyle1" TargetType=&qu ...
- hdu 4049 2011北京赛区网络赛J 状压dp ***
cl少用在for循环里 #include<cstdio> #include<iostream> #include<algorithm> #include<cs ...
- 基于能量收集的智能家居-2013国家级大学生创业实践项目申报_商业计划书_V0.2
SmartHome项目商业计划 基于能量收集的 免电池无线智能家居系统 IA-SmartHome团队 2012.12 l 基于无线的智能家居解决方案,节省施工成本: l 基于能 ...
- loj 1426(dfs + bfs)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1426 思路:首先我们预处理出每一个"*"在某一方向上最终能到达的位 ...
- BPEL是个什么东东
研究团队有个做智能服务组合的,其中用到叫BPEL的东西,因为全称是Business Process Execution Language,译成中文就是商业执行过程语言,这个东东的是整合SOA的一个执行 ...
- uri,url.urn
uri:Web上可用的每种资源 - HTML文档.图像.视频片段.程序等 - 由一个通过通用资源标志符(Universal Resource Identifier, 简称"URI" ...
- ontouchstart
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta cont ...
- vs 中怎么用c改变部分字体颜色
// test.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <windows.h> #include< ...
- 常用meta标签举例说明
本文是作者从百度百科和其他从网页中搜索到的资料,经综合整理,把常用meta标签列举并示例说明,仅供参考. 1.<meta charset="UTF-8"> --- ch ...
- Swift3.0语言教程字符串与文件的数据转换
Swift3.0语言教程字符串与文件的数据转换 Swift3.0语言教程字符串与文件的数据转换,如果想要对字符串中的字符进行永久保存,可以将字符串中的字符写入到文件中.当然,开发者也可以将写入的内容进 ...