This is a creation in Article, where the information may have evolved or changed.
PackageGobconnImport("Encoding/gob" "Errors" "NET" "Reflect" "Sync" "unsafe")typeMessagestruct{TypestringValue reflect. Value}func(Self message) Recovery () {putpointer (Self.value) putmsg (self)}func(Self message) Interface ()Interface{} {returnSelf.value.Elem (). Interface ()}/ * declares that a message pool is used to reuse objects * /varMsgpool sync. PoolfuncGetmsg () message {ifmsg, OK: = Msgpool.get (). (message); OK {returnMSG}returnmessage{}}funcPUTMSG (msg message) {Msgpool.put (msg)}typeGobconnectionstruct{RWC net. Conn enc *gob. Encoder Dec *gob. Decoder rlock sync. Mutex wlock sync. Mutex}typeGobconnectionInterface{Read () (MSG message, err Error) Write (msgInterface{}) (err error) Close () error localaddr () net. ADDR remoteaddr () net. ADDR}varGobpool sync. PoolfuncNewgobconnection (Conn net. Conn) Gobconnection {ifGCN, OK: = Gobpool.get (). (*gobconnection); OK {GCN.RWC = conn Gcn.enc = gob. Newencoder (conn) Gcn.dec = gob. Newdecoder (conn)returnGCN}return&gobconnection{rwc:conn, Enc:gob. Newencoder (conn), Dec:gob. Newdecoder (conn)}}typeMsgstructstruct{Structnamestring}var(rheadmsg = msgstruct{} wheadmsg = msgstruct{})func(Self *gobconnection) Read () (MSG message, err error) {Self.rlock.Lock ()deferSelf.rlock.Unlock () Err = Self.dec.Decode (&rheadmsg)ifErr! =Nil{return}varTyp reflect. Type Typ, err = Getmsgtype (rheadmsg.structname)ifErr! =Nil{return} msg = getmsg () Msg. Type = Rheadmsg.structnamevarValue = Getpointer (typ) Err = Self.dec.DecodeValue (value)ifErr! =Nil{msg. Recovery ()return} Msg.value = valuereturn}func(Self *gobconnection) Write (msgInterface{}) (err error) {Self.wlock.Lock () value: = Reflect. ValueOf (msg)ifValue. Kind () = = reflect. Interface | | Value. Kind () = = reflect. Ptr {wheadmsg.structname = value. Elem (). Type (). String ()}Else{wheadmsg.structname = value. Type (). String ()} err = Self.enc.Encode (wheadmsg)ifErr! =Nil{Self.wlock.Unlock ()return} err = Self.enc.EncodeValue (value) Self.wlock.Unlock ()return}func(Self *gobconnection) Close () error {Self.enc =NilSelf.dec =NilERR: = Self.rwc.Close () gobpool.put (self)returnErrfunc(Self *gobconnection) LOCALADDR () net. Addr {returnSELF.RWC.LOCALADDR ()}func(Self *gobconnection) REMOTEADDR () net. Addr {returnSELF.RWC.REMOTEADDR ()}/ * Request a fixed length of memory by specifying a type. * /var(Lock sync.) Mutex Ptrmap = Make(Map[string]*sync. Pool))funcGetpointer (Typ reflect. Type) reflect. Value {p, OK: = Ptrmap[typ. String ()]ifOK {ifValue, OK: = P.get (). (Reflect. Value); OK {returnValue}returnReflect. New (Typ)} lock. Lock () Ptrmap[typ. String ()] =New(Sync. Pool) lock. Unlock ()returnReflect. New (Typ)}funcPutpointer (value reflect. Value) {elem: = value. Elem (). Type () p, OK: = Ptrmap[elem. String ()]if!ok {lock. Lock () p =New(Sync. Pool) Ptrmap[elem. String ()] = P lock. Unlock ()} cleardata (Elem. Size (), unsafe. Pointer (value. Pointer ())) P.put (value)}/ * The type must be registered before the data is sent using this package. Otherwise receive can not be unpacked * /var(Typemap = Make(Map[string]reflect. Type) Errortype = errors. New ("type not register"))funcGetmsgtype (namestring) (reflect. Type, error) {Typ, OK: = Typemap[name]ifOK {returnTypNil}return Nil, Errortype}funcGetmsgalltype () []string{list: = Make([]string,0,Len(Typemap)) forName, _: =RangeTypemap {list =Append(list, name)}returnListfuncRegistertype (Typ reflect. Type) {Typemap[typ. String ()] = Typ}funcDeleteType (namestring) {Delete(Typemap, name)}/* Clear fixed-length memory data by specifying the memory start address, and the length. Do not use. Improper use may erase valid data * /funcClearData (SizeUIntPtr, ptr unsafe. Pointer) {varTemptrUIntPtr=UIntPtr(PTR)varStepUIntPtr=1 for{ifSize <=0{ Break}Switch{ Case1<= size && Size <8: Step =1 Case8<= size && Size < +: Step =8 Case +<= size && Size < -: Step = + CaseSize >= -: Step = -} cleardata (step, unsafe.) Pointer (temptr)) Temptr + = step Size-= step}}funcClearData (SizeUIntPtr, ptr unsafe. Pointer) {SwitchSize { Case1: *(*[1]byte) (PTR) =[1]byte{} Case8: *(*[8]byte) (PTR) =[8]byte{} Case +: *(*[]byte) (PTR) =[]byte{} Case -: *(*[ +]byte) (PTR) =[ +]byte{} }}