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架构学习笔记(九):自定义序列化协议
文章目录 为什么需要自定义序列化协议
随机推荐
- 网站通用登录模块代码 分类: ASP.NET 2014-12-06 10:49 615人阅读 评论(0) 收藏
1.HTML部分: <form id="form1" runat="server"> <script src=".. ...
- PHP连接打印机
<?php header("Content-type: text/html; charset=utf-8"); class Netprint{ public $host = ...
- memcached的最佳实践方案
基本问题 1.memcached的基本设置 1)启动Memcache的服务器端 # /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 ...
- [荐]jquery插件开发入门
http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html $.fn.myPlugin = function() { //在这里面,this指 ...
- JDBC操作MySQL数据库案例
JDBC操作MySQL数据库案例 import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepared ...
- CentOS升级Python 2.6到2.7
查看python的版本 python -V Python 2.6.6 下载Python Python-2.7.8.tar.xz 链接:http://pan.baidu.com/s/1i4 ...
- windows加入path路径
右键我的电脑,属性:高级系统设置,高级,环境变量:在系统变量中选path,编辑:将python安装路径加入即可(注意分号):
- ez_setup.py(安装python下setuptools用)
#!python"""Bootstrap setuptools installation If you want to use setuptools in your pa ...
- 用js刷题的一些坑
leecode可以用js刷题了,我大js越来越被认可了是吧.但是刷题中会因为忽略js的一些特性掉入坑里.我这里总结一下我掉过的坑. 坑1:js中数组对象是引用对象 js中除了object还有数组对象也 ...
- zepto下加载openbox弹出层
function fnOpenBox(objId,animateD,speed,tween,hide){ var oOpenBox = $(objId); oOpenBox.show(); oOpen ...