Go TCP test
Last Update:2015-06-18
Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed. 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)
}