示例#1
0
// 发送心跳包
func ping(conn *net.TCPConn) {
	ticker := time.NewTicker(60 * time.Second)
	for _ = range ticker.C {
		//write
		writePingMsg := &pb.PbClientPing{
			Ping:      proto.Bool(true),
			Timestamp: proto.Int64(time.Now().Unix()),
		}
		err := handlers.SendPbData(conn, packet.PK_ClientPing, writePingMsg)
		if err != nil {
			return
		}
		fmt.Println(conn.RemoteAddr().String(), "ping.")
	}
}
示例#2
0
// 处理收发数据包
func handlePackets(uuid int, conn *net.TCPConn, receivePackets <-chan *packet.Packet, chStop <-chan bool) {
	defer func() {
		if e := recover(); e != nil {
			log.Printf("Panic: %v\r\n")
		}
	}()
	for {
		select {
		case <-chStop:
			return

		// 消息包处理
		case p := <-receivePackets:
			if p.Type == packet.PK_ServerAcceptLogin { // 登陆回复
				// read
				readMsg := &pb.PbServerAcceptLogin{}
				packet.Unpack(p, readMsg)
				if readMsg.GetLogin() == true {
					log.Printf("[%v]: [%v]---[%v]\r\n", getUuid(uuid), readMsg.GetTipsMsg(), convert.TimestampToTimeString(readMsg.GetTimestamp()))
				}

				// write,随机向10个人发送消息
				for i := 0; i < 10; i++ {
					rand.Seed(time.Now().UnixNano())
					to_uuid := rand.Intn(total) + 1 // [1, total]
					if to_uuid == uuid {
						continue
					}

					writeMsg := &pb.PbC2CTextChat{
						FromUuid:  proto.String(getUuid(uuid)),
						ToUuid:    proto.String(getUuid(to_uuid)),
						TextMsg:   proto.String(strings.Repeat("hello,世界!!!", 100)),
						Timestamp: proto.Int64(time.Now().Unix()),
					}
					handlers.SendPbData(conn, packet.PK_C2CTextChat, writeMsg)
				}

			} else if p.Type == packet.PK_C2CTextChat { // 普通消息
				// read
				readMsg := &pb.PbC2CTextChat{}
				packet.Unpack(p, readMsg)
				from_uuid := readMsg.GetFromUuid()
				to_uuid := readMsg.GetToUuid()
				txt_msg := readMsg.GetTextMsg()
				timestamp := readMsg.GetTimestamp()
				if to_uuid != getUuid(uuid) {
					log.Printf("[%v]收到[%v]发来的不属于自己的包,该包应该属于[%v]\r\n", getUuid(uuid), from_uuid, to_uuid)
				} else {
					log.Printf("[%v]:[%v]收到来自[%v]的消息: [%v]", convert.TimestampToTimeString(timestamp), getUuid(uuid), from_uuid, txt_msg)

					// write, 回复时在原基础上加点消息,控制长度范围
					var to_txt_msg string
					var add_txt string = " 你好 hello world"

					if len(txt_msg)+len(add_txt) <= 2048 {
						to_txt_msg = txt_msg + add_txt
					} else {
						to_txt_msg = txt_msg
					}

					writeMsg := &pb.PbC2CTextChat{
						FromUuid:  proto.String(getUuid(uuid)),
						ToUuid:    proto.String(from_uuid),
						TextMsg:   proto.String(to_txt_msg),
						Timestamp: proto.Int64(time.Now().Unix()),
					}
					handlers.SendPbData(conn, packet.PK_C2CTextChat, writeMsg)
				}

			} else {
				log.Printf("[%v]收到未知包\r\n", getUuid(uuid))
			}
		}
	}
}
示例#3
0
// 模拟客户端(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
				}
			}
		}
	}
}
示例#4
0
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
// 模拟客户端(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,
		}
	}
}
示例#6
0
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
	}
	// read
	buf := make([]byte, 1024)
	n, err := conn.Read(buf)
	if err != nil {
		log.Printf("%v 登陆回应包读取失败: %v\r\n", i_uuid, err)
		return
	}
	pac := getPacFromBuf(buf, n)
	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
		}
	}()

	// 死循环,接收消息和发送消息
	recBuf := make([]byte, 1024)
	for {
		fmt.Println("坐等消息到来...")
		// read
		n, err := conn.Read(recBuf)
		if err != nil {
			log.Printf("%v 读取消息失败: %v\r\n", i_uuid, err)
			return
		}
		fmt.Println("消息读取完毕")
		pac := getPacFromBuf(recBuf, n)
		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
		}
	}
}