This is a creation in Article, where the information may have evolved or changed.
Occlient Project Main.gopackage mainimport ("Crypto/md5" "Encoding/hex" "Flag" "Log" "OS" "Runtime" "Time") func MD5 (b [] BYTE) string {h: = MD5. New () h.write (b) x: = H.sum (nil) y: = make ([]byte, +) hex. Encode (y, x) return string (y)}var sleep time. Durationfunc Datetime_yyyymmddhhmmss () string {return time. Now (). Format ("20060102150405")}func Main () {runtime. Gomaxprocs (1000000) Addr: = flag. String ("addr", "127.0.0.1:5555", "Message server address and port, default 180.153.149.147:8443") User: = Flag. Int ("UID", 10000, "User login Id,default 10000") sec: = flag. String ("SEC", "abc", "Secrity key"): = flag. Int ("Rid", 11111, "client Type,default 11111") c: = flag. Int ("C", 1, "concurrent Number,default 1") T: = flag. Int ("T", 1, "precent%t% second send a message, default 1 S") Sleep = time. Duration (*t) * time. Secondflag.parse () for I: = 1; I <= *c; i++ {Go Doconnect (*addr, Int32 (*user) +int32 (i), Int32 (*room), *sec)}select {}os. Exit (0)}func doconnect (addr string, uid Int32, Hostel Int32, key string) {ClieNT: = newclient (addr, uid, guest, key) for {OK: = client. Handshake () If OK {ok = client. Join () break}client. Logout () log. Printf ("Reconnect%+v", client)}//partten: = "20060102150405" for {if client. IsLogin () {client. SendMessage ("Hello openchat") time. Sleep (Sleep)} else {client. Logout () doconnect (addr, uid, guest, key)}}//defer client. Logout ()//defer client. Logout ()}func checkerror (msg string, err Error) {if err! = Nil {log. PRINTLN (msg, err)}}//occlientpackage mainimport ("bytes" "encoding/binary" "io" "Log" "NET" "Time") type Client struct { Address stringuserid int32roomid int32seckey stringsequence int32logined boolsession net. Connnextint func () Int32}func newclient (addr string, user Int32,, key String) int32 {c: = new (Client) *client nce = 0c. Address = ADDRC. UserId = UserC. Roomid = Roomc. Seckey = keyc.logined = Falsec.nextint = Intseq () return C}func intseq () func () int32 {var i int32 = 0return func () int32 { i + = 1return I}}func (c *client) IsLogin () bool {return C.logined}func (c *client) Logout () {c.logined = Falseif c.session! = nil {c.session.close ()}}func readpacket (conn net. Conn) ([]byte, error) {result: = bytes. Newbuffer (nil) TB: = Make ([]byte, 4) Conn. Setreaddeadline (time. Now (). ADD (time. Second *)) I, err: = Io. READFULL (conn, TB) result. Write (tb[0:i]) if err! = Nil {return result. Bytes (), err}var length int32err = binary. Read (result, binary. Bigendian, &length) If length > 4096 {conn. Close () log. Printf ("Invalid length%d", length) return result. Bytes (), Err}result = Bytes. Newbuffer (nil) result. Write (TB) TB = make ([]byte, length) conn. Setreaddeadline (time. Now (). ADD (time. Second *)) I, err = io. READFULL (conn, TB) result. Write (TB) return result. Bytes (), Err}func (c *client) join () bool {join: = Newpacket (C.nextint (), Message_join) join. AddTagInt32 (Tag_clientid, C.userid) join. AddTagInt32 (Tag_roomid, c.roomid) b, err: = join. Encode ()//log. Printf ("Send Hex%x%s", B, join.) String ())//conn. Write () _, err = C.session.write (b) checkerror ("Join", err) return err! = nil//b, err = Readpacket (conn)//checkerror (ERR)//if err! = Nil {//return false//}//join. Decode (b)//log. Printf ("Recv Hex%x%s", B, join.) String ())//return True}func (c *client) handshake () bool {_, Err: = Net. RESOLVETCPADDR ("TCP4", c.address) checkerror ("Handshake resolvetcpaddr", err) if err! = Nil {return false}conn, err: = Net. Dialtimeout ("TCP", C.address, time. SECOND*30)//net. DIALTCP ("TCP", Nil, tcpaddr) checkerror ("Handshake dialtimeout", err) if err! = Nil {return false}conn. (*net. Tcpconn). Setkeepalive (TRUE) Conn. (*net. Tcpconn). Setnodelay (true) c.session = Connhandshake: = Newhandshake (C.seckey) b, err: = handshake. Encode () _, err = conn. Write (b)//log. Printf ("Send Hex%d%x%s", I, B, handshake. String ()) checkerror ("Handshake Write", err) b, err = Readpacket (conn) checkerror ("Handshake Read", err) if err! = Nil {retur N False}handshake. Decode (b)//log. Printf ("Recv Hex%x%s", B, handshake. String ()) c.logined = Truego Loop (conn) return True}func (c *client) SendMessage (text string) bool {chat: = NewpAcket (C.nextint (), Message_chat) CHAT. AddTagInt32 (Tag_from, C.userid) chat. AddTagInt32 (tag_to, C.roomid) chat. Addtagstring (tag_content, text) b, err: = Chat. Encode ()//log. Printf ("Send Hex%x%s", B, chat.) String ()) _, err = C.session.write (b) checkerror ("SendMessage Write", err) if err! = Nil {c.logined = False}return err! = Nil }func Loop (conn net. Conn) {for {//conn. Setreaddeadline (time. Now (). ADD (time. Second *)) b, err: = Readpacket (conn) checkerror ("Loop readpacket", err) if err! = Nil {break}pk: = new (Packet) Err = pk. Decode (b) checkerror ("Loop Decode", err) if Err = = Nil {//log. Printf ("Receive Hex%x%s", B, Pk.) String ())} else {log. Printf ("Receive Hex%x", b)}}log. Printf ("Loop exit%+v/%+v", Conn. LOCALADDR (), Conn. Remoteaddr ())}//protocolpackage mainimport ("bytes" "Encoding/binary" "FMT" "Log" "Math/rand" "StrConv" "Time") const ( Tag_code int32 = 0tag_clientid int32 = 1tag_from int32 = 2tag_to int32 = 3tag_roomid int32 = 4tag_content Int32 = 5//stringtag_icon int32 = 6//string) Const (Message_join int32 = 1message_leave int32 = 2message_chat int32 = 3message_userlist Int32 = 4ack_message int32 = 0x0keepalive_message int32 = 111ack_keepalive_message int32 = 0x1111unknown_m essage int32 = 0x7474) type packetencodeerror struct {Err string}func (e *packetencodeerror) Error () string {return E . Err}type handshake struct {packetlength int32random int32timestamp int32version bytesignature string//MD 5 (Key +yyyymmddhhmmss+random+version)}type TLV struct {tag int32length int32value []byte}func NEWTLV (tag int32, Value St Ring) *TLV {TLV: = new (TLV) TLV. Tag = TAGTLV. Value = []byte (value) TLV. Length = Int32 (Len (TLV). Value)) return Tlv}func NewTlv1 (tag Int32, value Int32) *tlv {TLV: = new (TLV) TLV. Tag = tagbuf: = bytes. Newbuffer (nil) binary. Write (buf, Binary. Bigendian, &value) TLV. Value = buf. Bytes () TLV. Length = 4return Tlv}func (P *TLV) Encode () []byte {buf: = bytes. Newbuffer (nil) binary. Write (buf, Binary. BigEndian, P.tag) binary. Write (buf, Binary. Bigendian, P.length) buf. Write (P.value) return BUF. Bytes ()}func (P *TLV) Decode (b []byte) error {return nil}type Packet struct {packetlength int32sequence int32timestamp Int32messagetype int32tags []tlv}func newpacket (Seq Int32, Mtype Int32) *packet {Packet: = new (Packet) Packet. Sequence = Seqpacket. Timestamp = Int32 (time. Now (). Unix ()) packet. MessageType = Mtypepacket. Tags = Make ([]TLV, 0) return Packet}func (P *packet) Encode () ([]byte, error) {buf: = bytes. Newbuffer (nil) Err: = Binary. Write (buf, Binary. Bigendian, p.sequence) err = binary. Write (buf, Binary. Bigendian, p.timestamp) err = binary. Write (buf, Binary. Bigendian, P.messagetype) for I: = 0; I < Len (p.tags); i++ {TLV: = P.tags[i]buf. Write (TLV. Encode ())}b: = buf. Bytes () P.packetlength = Int32 (len (b)) buf = Bytes. Newbuffer (nil) err = binary. Write (buf, Binary. Bigendian, P.packetlength) buf. Write (b) return BUF. Bytes (), Err}func (P *packet) Decode (b []byte) error {buf: = Bytes. Newbuffer (Nil) _, Err: = buf. Write (b) Err = binary. Read (buf, Binary. Bigendian, &p.packetlength) if Int32 (Len (b))! = p.packetlength+4 {log. Printf ("Invaild packetlength%d/%d", Len (b), p.packetlength) buf = bytes. Newbuffer (Nil) _, err = buf. Write (b)}err = binary. Read (buf, Binary. Bigendian, &p.sequence) err = binary. Read (buf, Binary. Bigendian, &p.timestamp) err = binary. Read (buf, Binary. Bigendian, &p.messagetype) for Len (buf. Bytes ()) > 0 {var t, L Int32binary. Read (buf, Binary. Bigendian, &t) binary. Read (buf, Binary. Bigendian, &l) if L > 4096 {log. Printf ("Invaild Tag Length%d/%d", T, l) Break}b: = Make ([]byte, L) buf. Read (b) P.addtag (Tlv{t, L, b})}return Err}func (P *packet) addtagstring (tag int32, value string) {TLV: = Tlv{tag:tag, Valu E: []byte (value)}TLV. Length = Int32 (Len (TLV). Value)) P.tags = append (P.tags, TLV)}func (P *packet) AddTagInt32 (tag Int32, value Int32) {TLV: = Tlv{tag:tag, length:4}b UF: = bytes. Newbuffer (nil) binary. Write (buf, Binary. Bigendian, &value) TLV. Value = buf. Bytes () p.tags = append (P.tags, TLV)}func (P *packet) Addtag (tag tlv) {p.tags = append (p.tags, tag)}func (P *packet) String () string {return FMT. Sprintf ("Packet%+v", *p)}func Newhandshake (key string) *handshake {handshake: = new (handshake) handshake. Random = Rand. INT31 () handshake. Timestamp = Int32 (time. Now (). Unix ()) handshake. Version = 1handshake. Signature = MD5 ([]byte (key + StrConv). Formatint (Int64 (handshake. Timestamp) + StrConv. Formatint (Int64 (handshake. Random) + StrConv. Itoa (int (handshake). Version)))//handshake. Packetlength = 4 + 4 + 1 + int32 (Len ([]byte (handshake). Signature)) return Handshake}func (P *handshake) Encode () ([]byte, error) {buf: = bytes. Newbuffer (nil) b: = []byte (p.signature) P.packetlength = Int32 (len (b) + 9) Err: = Binary. Write (buf, Binary. Bigendian, p.packetlength) err = binary. Write (buf, Binary. Bigendian, p.random) err = binary. Write (buf, Binary. Bigendian, p.timestamp) err = binary. Write (buf, Binary. Bigendian, P.version) _, err = buf. Write (b) return BUF. Bytes (),Err}func (P *handshake) Decode (b []byte) error {if Len (b) >= {buf: = bytes. Newbuffer (Nil) _, Err: = buf. Write (b) Err = binary. Read (buf, Binary. Bigendian, &p.packetlength) err = binary. Read (buf, Binary. Bigendian, &p.random) err = binary. Read (buf, Binary. Bigendian, &p.timestamp) err = binary. Read (buf, Binary. Bigendian, &p.version) p.signature = string (buf. Bytes ())//p.packetlength = Int32 (len (b)) return Err}return &packetencodeerror{"Invalid pakcetlength" + String (len ( b))}}func (P *handshake) string () string {return FMT. Sprintf ("Handshake%+v", *p)}
Reprint Address: http://www.oschina.net/code/snippet_874_17443