gitee.com/KyleChenSource/lib-robot@v1.0.2/robottest/robot/net/network_tcp.go (about) 1 package net 2 3 import ( 4 "fmt" 5 "io" 6 "net" 7 "sync" 8 9 "gitee.com/KyleChenSource/lib-robot/robottest/common" 10 "gitee.com/KyleChenSource/lib-robot/robottest/protos" 11 ) 12 13 // 接口都只允许在一个goroutine中调用 14 type ClientTcp struct { 15 _handler IClientHandler 16 _msglen_get MsgLenGet 17 _msgmin_get MsgMinGet 18 _msg_decode MsgDecode 19 _msg_encode MsgEncode 20 _tcp *net.TCPConn 21 22 _join *sync.WaitGroup // 用来等待开启的协程结束 23 _closing bool // 正在关闭中标记位。因为chan的容量,导致了关闭可能死锁 24 } 25 26 func (this *ClientTcp) Initialize(h IClientHandler, func_msglen_get MsgLenGet, func_msgmin_get MsgMinGet, func_msg_decode MsgDecode, func_msg_encode MsgEncode) error { 27 this._handler = h 28 this._msglen_get = func_msglen_get 29 this._msgmin_get = func_msgmin_get 30 this._msg_decode = func_msg_decode 31 this._msg_encode = func_msg_encode 32 33 return nil 34 } 35 36 func (this *ClientTcp) co_recv() { 37 defer func() { 38 this._join.Done() 39 }() 40 defer common.PanicLog(func() { 41 this._handler.MsgChannel() <- &Msg{ 42 Type: MSGTYPE_ERR, 43 Err: fmt.Errorf("recv panic error"), 44 } 45 }) 46 47 minlen := this._msgmin_get() 48 minBuf := make([]byte, minlen) 49 rl := 0 // 目前接收数据长度 50 for { 51 r, err := this._tcp.Read(minBuf[rl:]) 52 if err != nil { 53 this._handler.MsgChannel() <- &Msg{ 54 Type: MSGTYPE_ERR, 55 Err: err, 56 } 57 break 58 } 59 60 if r == 0 { 61 this._handler.MsgChannel() <- &Msg{ 62 Type: MSGTYPE_ERR, 63 Err: fmt.Errorf("disconnected by remote"), 64 } 65 break 66 } 67 68 rl += r 69 if rl < minlen { 70 continue 71 } 72 73 msglen, err := this._msglen_get(minBuf) 74 if err != nil { 75 this._handler.MsgChannel() <- &Msg{ 76 Type: MSGTYPE_ERR, 77 Err: err, 78 } 79 break 80 } 81 82 msgBuf := make([]byte, msglen) 83 copy(msgBuf, minBuf) 84 85 if msglen <= minlen { 86 // 包已经足够大 87 copy(minBuf, minBuf[msglen:]) 88 rl = minlen - msglen 89 } else { 90 rl = 0 91 _, err = io.ReadFull(this._tcp, msgBuf[minlen:]) 92 if err != nil { 93 this._handler.MsgChannel() <- &Msg{ 94 Type: MSGTYPE_ERR, 95 Err: err, 96 } 97 break 98 } 99 } 100 101 // protoId, err := this._msg_decodeprotoid(msgBuf) 102 // if err != nil { 103 // this._handler.MsgChannel() <- &Msg{ 104 // Type: MSGTYPE_ERR, 105 // Err: err, 106 // } 107 // break 108 // } 109 110 // switch this._msg_filtertype { 111 // case ProtoFilterType_Focus: 112 // _, ok := this._msg_filter.Load(protoId) 113 // if !ok { 114 // continue 115 // } 116 // default: 117 // _, ok := this._msg_filter.Load(protoId) 118 // if ok { 119 // continue 120 // } 121 // } 122 123 // protoId, header, data, err := this._msg_decode(msgBuf) 124 // if err != nil { 125 // this._handler.MsgChannel() <- &Msg{ 126 // Type: MSGTYPE_ERR, 127 // Err: err, 128 // } 129 // break 130 // } 131 132 this._handler.MsgChannel() <- &Msg{ 133 Type: MSGTYPE_RECV, 134 Data: msgBuf, 135 } 136 } 137 } 138 139 func (this *ClientTcp) connect(addr string) { 140 defer common.PanicLog(func() { 141 this._handler.MsgChannel() <- &Msg{ 142 Type: MSGTYPE_ERR, 143 Err: fmt.Errorf("connect panic error"), 144 } 145 }) 146 147 tcp, err := net.Dial("tcp", addr) 148 if err != nil { 149 this._handler.MsgChannel() <- &Msg{ 150 Type: MSGTYPE_ERR, 151 Err: err, 152 } 153 this._join.Done() 154 return 155 } 156 157 this._tcp = tcp.(*net.TCPConn) 158 err = this._tcp.SetLinger(5) 159 if err != nil { 160 this._handler.MsgChannel() <- &Msg{ 161 Type: MSGTYPE_ERR, 162 Err: err, 163 } 164 this._join.Done() 165 return 166 } 167 168 this._handler.MsgChannel() <- &Msg{ 169 Type: MSGTYPE_CONNECTED, 170 } 171 172 go this.co_recv() 173 } 174 175 func (this *ClientTcp) Start(addr string) error { 176 // 不能使用this._tcp作为判断,因为连接过程中_tcp == nil 177 if this._join != nil { 178 return fmt.Errorf("ClientTcp Not Close") 179 } 180 181 this._closing = false 182 183 this._join = &sync.WaitGroup{} 184 this._join.Add(1) 185 go this.connect(addr) 186 187 return nil 188 } 189 190 func (this *ClientTcp) join() { 191 if this._join != nil { 192 this._join.Wait() 193 this._join = nil 194 } 195 196 this._tcp = nil 197 198 this._handler.MsgChannel() <- &Msg{ 199 Type: MSGTYPE_CLOSED, 200 } 201 } 202 203 func (this *ClientTcp) Close() { 204 if this._closing { 205 return 206 } 207 208 this._closing = true 209 if this._tcp != nil { 210 this._tcp.Close() 211 } 212 213 go this.join() 214 } 215 216 func (this *ClientTcp) Send(protoId protos.ProtoID, data protos.JsonString) error { 217 bytes, err := this._msg_encode(protoId, data) 218 if err != nil { 219 return err 220 } 221 222 l := len(bytes) 223 for l > 0 { 224 s, err := this._tcp.Write(bytes) 225 if err != nil { 226 this._handler.MsgChannel() <- &Msg{ 227 Type: MSGTYPE_ERR, 228 Err: err, 229 } 230 return err 231 } 232 233 l -= s 234 bytes = bytes[s:] 235 } 236 237 return nil 238 }