go TCP 测试

package main


import (
"fmt"
"net"
"os"
"time"
"encoding/binary"
"bytes"
"compress/zlib"
"io/ioutil"
"runtime"
// "github.com/ugorji/go/codec"
)


var ConnectionCount int = 0


func main() {
runtime.GOMAXPROCS(2)
service := ":1400"
tcpAddr, err := net.ResolveTCPAddr("tcp", service)
checkError(err)
TCPListener, err := net.ListenTCP("tcp", tcpAddr)
defer TCPListener.Close()
checkError(err)


st := time.Now()
fmt.Printf("time:%s\n", time.Now().String())


go func() {
for {
time.Sleep(time.Second * 30)
fmt.Printf("connection count %d\n", ConnectionCount)
}
}()


fmt.Printf("use time:%s\n", time.Now().Sub(st).String())


for {
conn, err := TCPListener.AcceptTCP()
if err != nil {
continue
}
go handleClientConn(ClientConn{conn, map[string]ClientHandler{"register": func(req []byte, res []byte) error  {
res = append(res, req...)
return nil
}}, false})
}
}


func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
}


type DataHeader struct {
DataLen uint32
NameLen uint16
Name string
}
const HeaderLength = 6


type ClientHandler func(request []byte, response []byte) error


type ClientConn struct {
Conn net.Conn
DispatchHandlers map[string]ClientHandler
Done bool
}


func (client *ClientConn)Dispatch(method string, data []byte) {
fmt.Printf("dispatch(%s)", method)
handler, ok := client.DispatchHandlers[method]
if ok && handler != nil {
reader, err := zlib.NewReader(bytes.NewReader(data))
if err != nil {
// TODO: handler error
}
uncompressed, err := ioutil.ReadAll(reader)
fmt.Printf("data:%s", uncompressed)


result := make([]byte, 1024)
err = handler(data, result)


if err != nil {
// TODO: handler error
}


fmt.Printf("write back(%s)", result)


binary.Write(client.Conn, binary.BigEndian, uint32(len(result)))
binary.Write(client.Conn, binary.BigEndian, uint16(len(method)))
client.Conn.Write([]byte(method))


n, err := client.Conn.Write(result)
if n != len(result) || err != nil {
fmt.Printf("len:%d, write:%d, err:%s", len(result), n, err)
}
} else {
fmt.Printf("no handler found (%s)", method)
}
}


func (client *ClientConn)ReadPacket() {
conn := client.Conn
buff := bytes.NewBuffer(nil)
chunk := make([]byte, 1024)
header := DataHeader{}


for {
n, err := conn.Read(chunk)
if err != nil {
fmt.Printf("err:%s", err)
return
}
buff.Write(chunk[:n])


if buff.Len() >= HeaderLength {
binary.Read(buff, binary.BigEndian, &header.DataLen)
binary.Read(buff, binary.BigEndian, &header.NameLen)


for buff.Len() < int(header.NameLen) {
n, err := conn.Read(chunk)
if err != nil {
fmt.Printf("err:%s", err)
return
}
buff.Write(chunk[:n])
}


nameBuf := make([]byte, header.NameLen)


binary.Read(buff, binary.BigEndian, nameBuf)
methodName := string(nameBuf)
fmt.Printf("methodname(%s)\n", methodName)


for buff.Len() < int(header.DataLen) {
n, err := conn.Read(chunk)
if err != nil {
fmt.Printf("err:%s", err)
return
}
buff.Write(chunk[:n])
}


packet := buff.Bytes()[:header.DataLen]
left := buff.Bytes()[header.DataLen:]


buff.Reset()
buff.Write(left)


fmt.Printf("packet(%d:%s)", header.DataLen, packet)
client.Dispatch(methodName, packet)
}
}
}






func handleClientConn(client ClientConn) {
ConnectionCount += 1
defer func() { ConnectionCount -= 1}()


conn := client.Conn


fmt.Printf("conn(%#v) connected\n", conn)
defer conn.Close()


client.ReadPacket()


fmt.Printf("handler conn(%#v) exit\n", conn)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值