Go Language Network Programming Example-client Chapter

Source: Internet
Author: User
Tags key string sprintf
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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.