コード例 #1
0
ファイル: client_main.go プロジェクト: jackwanger/chatserver
func getPacFromBuf(buf []byte, n int) *packet.Packet {
	pacLen := convert.BytesToUint32(buf[0:4])
	pac := &packet.Packet{
		Len:  pacLen,
		Type: convert.BytesToUint32(buf[4:8]),
		Data: buf[8:pacLen],
	}

	if n != int(pacLen) {
		fmt.Println("Len:", pac.Len)
		fmt.Println("Type:", pac.Type)
		fmt.Println("Data:", pac.Data)
		fmt.Println("数据不完整")
		return nil
	}

	return pac
}
コード例 #2
0
ファイル: press.go プロジェクト: jackwanger/chatserver
// 模拟客户端(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
				}
			}
		}
	}
}
コード例 #3
0
ファイル: server.go プロジェクト: cautonwong/chatserver
func (this *Server) handleClientConn(conn *net.TCPConn) {
	this.waitGroup.Add(1)
	defer this.waitGroup.Done()

	receivePackets := make(chan *packet.Packet, 100) // 接收到的包
	chStop := make(chan bool)                        // 通知停止消息处理
	addr := conn.RemoteAddr().String()

	defer func() {
		defer func() {
			if e := recover(); e != nil {
				log.Printf("Panic: %v\r\n", e)
			}
		}()

		handlers.CloseConn(conn)

		log.Printf("Disconnect: %v\r\n", addr)
		chStop <- true
	}()

	// 处理接收到的包
	go this.handlePackets(conn, receivePackets, chStop)

	// 接收数据
	log.Printf("HandleClient: %v\r\n", addr)

	// 包长(4) + 类型(4) + 包体(len(pacData))
	var (
		bLen   []byte = make([]byte, 4)
		bType  []byte = make([]byte, 4)
		pacLen uint32
	)

	for {
		select {
		case <-this.exitCh:
			log.Printf("Stop handleClientConn\r\n")
			return
		default:
		}

		conn.SetReadDeadline(time.Now().Add(this.readTimeout))

		if n, err := io.ReadFull(conn, bLen); err != nil && n != 4 {
			log.Printf("Read pacLen failed: %v\r\n", err)
			return
		}
		if n, err := io.ReadFull(conn, bType); err != nil && n != 4 {
			log.Printf("Read pacType failed: %v\r\n", err)
			return
		}
		if pacLen = convert.BytesToUint32(bLen); pacLen > this.maxPacLen {
			log.Printf("pacLen larger than maxPacLen\r\n")
			return
		}

		pacData := make([]byte, pacLen-8)
		if n, err := io.ReadFull(conn, pacData); err != nil && n != int(pacLen) {
			log.Printf("Read pacData failed: %v\r\n", err)
			return
		}

		receivePackets <- &packet.Packet{
			Len:  pacLen,
			Type: convert.BytesToUint32(bType),
			Data: pacData,
		}
	}
}
コード例 #4
0
ファイル: client_main.go プロジェクト: cautonwong/chatserver
func testBB(i_uuid string) {
	tcpAddr, _ := net.ResolveTCPAddr("tcp4", config.Addr)
	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		log.Printf("%v DialTCP失败: %v\r\n", i_uuid, err)
		return
	}
	defer conn.Close()

	// 登陆
	// write
	writeLoginMsg := &pb.PbClientLogin{
		Uuid:      proto.String(i_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", i_uuid, err)
		return
	}

	var (
		bLen   []byte = make([]byte, 4)
		bType  []byte = make([]byte, 4)
		pacLen uint32
	)

	// read
	if n, err := io.ReadFull(conn, bLen); err != nil && n != 4 {
		log.Printf("Read pacLen failed: %v\r\n", err)
		return
	}
	if n, err := io.ReadFull(conn, bType); err != nil && n != 4 {
		log.Printf("Read pacType failed: %v\r\n", err)
		return
	}
	if pacLen = convert.BytesToUint32(bLen); pacLen > uint32(2048) {
		log.Printf("pacLen larger than maxPacLen\r\n")
		return
	}
	pacData := make([]byte, pacLen-8)
	if n, err := io.ReadFull(conn, pacData); err != nil && n != int(pacLen) {
		log.Printf("Read pacData failed: %v\r\n", err)
		return
	}
	pac := &packet.Packet{
		Len:  pacLen,
		Type: convert.BytesToUint32(bType),
		Data: pacData,
	}

	readAccepLoginMsg := &pb.PbServerAcceptLogin{}
	err = packet.Unpack(pac, readAccepLoginMsg)
	if err != nil {
		log.Printf("%v Unpack error: %v\r\n", i_uuid, err)
		return
	}
	fmt.Println(readAccepLoginMsg.GetLogin())
	fmt.Println(readAccepLoginMsg.GetTipsMsg())
	fmt.Println(convert.TimestampToTimeString(readAccepLoginMsg.GetTimestamp()))

	// 定时发送心跳包
	go ping(conn)

	// 先向对方发送消息
	// write
	go func() {
		writeC2CMsg := &pb.PbC2CTextChat{
			FromUuid:  proto.String(i_uuid),
			ToUuid:    proto.String(u_uuid),
			TextMsg:   proto.String("hi, 我的uuid是: " + i_uuid),
			Timestamp: proto.Int64(time.Now().Unix()),
		}
		err := handlers.SendPbData(conn, packet.PK_C2CTextChat, writeC2CMsg)
		if err != nil {
			log.Printf("%v 发送消息失败: %v\r\n", i_uuid, err)
			return
		}
	}()

	// 死循环,接收消息和发送消息
	for {
		fmt.Println("坐等消息到来...")
		// read
		if n, err := io.ReadFull(conn, bLen); err != nil && n != 4 {
			log.Printf("Read pacLen failed: %v\r\n", err)
			return
		}
		if n, err := io.ReadFull(conn, bType); err != nil && n != 4 {
			log.Printf("Read pacType failed: %v\r\n", err)
			return
		}
		if pacLen = convert.BytesToUint32(bLen); pacLen > uint32(2048) {
			log.Printf("pacLen larger than maxPacLen\r\n")
			return
		}
		pacData := make([]byte, pacLen-8)
		if n, err := io.ReadFull(conn, pacData); err != nil && n != int(pacLen) {
			log.Printf("Read pacData failed: %v\r\n", err)
			return
		}
		pac := &packet.Packet{
			Len:  pacLen,
			Type: convert.BytesToUint32(bType),
			Data: pacData,
		}
		readC2CMsg := &pb.PbC2CTextChat{}
		err = packet.Unpack(pac, readC2CMsg)
		if err != nil {
			log.Printf("%v 读取到的消息Unpack error: %v\r\n", i_uuid, err)
			return
		}

		from_uuid := readC2CMsg.GetFromUuid()
		to_uuid := readC2CMsg.GetToUuid()
		txt_msg := readC2CMsg.GetTextMsg()
		timestamp := readC2CMsg.GetTimestamp()

		fmt.Println("from_uuid:", from_uuid)
		fmt.Println("to_uuid:", to_uuid)
		fmt.Println("txt_msg:", txt_msg)
		fmt.Println("timestamp:", convert.TimestampToTimeString(timestamp))

		time.Sleep(5 * time.Second)

		// write
		writeC2CMsg := &pb.PbC2CTextChat{
			FromUuid:  proto.String(to_uuid),
			ToUuid:    proto.String(from_uuid),
			TextMsg:   proto.String(txt_msg + "我是 " + i_uuid),
			Timestamp: proto.Int64(timestamp),
		}
		err = handlers.SendPbData(conn, packet.PK_C2CTextChat, writeC2CMsg)
		if err != nil {
			log.Printf("%v 回复消息失败: %v\r\n", i_uuid, err)
			return
		}
	}
}
コード例 #5
0
ファイル: server.go プロジェクト: jackwanger/chatserver
func (this *Server) handleClientConn(conn *net.TCPConn) {
	this.waitGroup.Add(1)
	defer this.waitGroup.Done()

	receivePackets := make(chan *packet.Packet, 20) // 接收到的包
	chStop := make(chan bool)                       // 通知停止消息处理
	addr := conn.RemoteAddr().String()

	defer func() {
		defer func() {
			if e := recover(); e != nil {
				log.Printf("Panic: %v\r\n", e)
			}
		}()

		handlers.CloseConn(conn)

		log.Printf("Disconnect: %v\r\n", addr)
		chStop <- true
	}()

	// 处理接收到的包
	go this.handlePackets(conn, receivePackets, chStop)

	// 接收数据
	log.Printf("HandleClient: %v\r\n", addr)

	request := this.reqMemPool.Get().([]byte)
	defer this.reqMemPool.Put(request)

	rbuf := this.rbufMemPool.Get().(*ringbuffer.RingBuffer)
	defer this.rbufMemPool.Put(rbuf)

	for {
		select {
		case <-this.exitCh:
			log.Printf("Stop handleClientConn\r\n")
			return
		default:
		}

		conn.SetReadDeadline(time.Now().Add(this.readTimeout))

		readSize, err := conn.Read(request)
		if err != nil {
			log.Printf("Read failed: %v\r\n", err)
			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
				}
			}
		}

	}
}
コード例 #6
0
ファイル: press.go プロジェクト: cautonwong/chatserver
// 模拟客户端(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, 100) // 接收到的包
	chStop := make(chan bool)                        // 通知停止消息处理

	defer func() {
		conn.Close()
		chStop <- true
	}()

	// 发送心跳包
	go ping(conn)

	// 处理接受到的包
	go handlePackets(uuid, conn, receivePackets, chStop)

	// 包长(4) + 类型(4) + 包体(len(pacData))
	var (
		bLen   []byte = make([]byte, 4)
		bType  []byte = make([]byte, 4)
		pacLen uint32
	)

	for {
		if n, err := io.ReadFull(conn, bLen); err != nil && n != 4 {
			log.Printf("Read pacLen failed: %v\r\n", err)
			return
		}
		if n, err := io.ReadFull(conn, bType); err != nil && n != 4 {
			log.Printf("Read pacType failed: %v\r\n", err)
			return
		}
		if pacLen = convert.BytesToUint32(bLen); pacLen > uint32(2048) {
			log.Printf("pacLen larger than maxPacLen\r\n")
			return
		}

		pacData := make([]byte, pacLen-8)
		if n, err := io.ReadFull(conn, pacData); err != nil && n != int(pacLen) {
			log.Printf("Read pacData failed: %v\r\n", err)
			return
		}

		receivePackets <- &packet.Packet{
			Len:  pacLen,
			Type: convert.BytesToUint32(bType),
			Data: pacData,
		}
	}
}