func NewServer() *Server { return &Server{ exitCh: make(chan bool), waitGroup: &sync.WaitGroup{}, funcMap: funcmap.NewFuncMap(), acceptTimeout: 30, readTimeout: 60, writeTimeout: 60, reqMemPool: &sync.Pool{ New: func() interface{} { return make([]byte, 1024) }, }, rbufMemPool: &sync.Pool{ New: func() interface{} { return ringbuffer.NewRingBuffer(1024) }, }, } }
// 模拟客户端(uuid) func testClient(uuid int) { defer func() { if e := recover(); e != nil { log.Printf("uuid: [%v] Panic: %v\r\n", getUuid(uuid), e) } }() // 连接服务器 tcpAddr, _ := net.ResolveTCPAddr("tcp4", config.Addr) conn, err := net.DialTCP("tcp", nil, tcpAddr) if err != nil { log.Printf("[%v] DialTCP失败: %v\r\n", getUuid(uuid), err) return } // 发送登陆请求 writeLoginMsg := &pb.PbClientLogin{ Uuid: proto.String(getUuid(uuid)), Version: proto.Float32(3.14), Timestamp: proto.Int64(time.Now().Unix()), } err = handlers.SendPbData(conn, packet.PK_ClientLogin, writeLoginMsg) if err != nil { log.Printf("[%v] 发送登陆包失败: %v\r\n", getUuid(uuid), err) return } // 下面这些处理和server.go中的一样 receivePackets := make(chan *packet.Packet, 20) // 接收到的包 chStop := make(chan bool) // 通知停止消息处理 request := make([]byte, 1024) rbuf := ringbuffer.NewRingBuffer(1024) defer func() { conn.Close() chStop <- true }() // 发送心跳包 go ping(conn) // 处理接受到的包 go handlePackets(uuid, conn, receivePackets, chStop) for { readSize, err := conn.Read(request) if err != nil { return } if readSize > 0 { rbuf.Write(request[:readSize]) // 包长(4) + 类型(4) + 包体(len([]byte)) for { if rbuf.Size() >= 8 { pacLen := convert.BytesToUint32(rbuf.Bytes(4)) if rbuf.Size() >= int(pacLen) { rbuf.Peek(4) receivePackets <- &packet.Packet{ Len: pacLen, Type: convert.BytesToUint32(rbuf.Read(4)), Data: rbuf.Read(int(pacLen) - 8), } } else { break } } else { break } } } } }