Ejemplo n.º 1
0
func (this *Agent) Run() {
	this.LoadRegIds()

	conn, err := net.DialTCP("tcp", nil, this.serverAddr)
	if err != nil {
		log.Errorf("Dial %v error: %s", this.serverAddr, err.Error())
		log.Flush()
		os.Exit(1)
		return
	}
	defer func() {
		conn.Close()
	}()

	dataInit := packet.PktDataInit{
		DevId: this.deviceId,
	}

	initPkt, err := packet.Pack(packet.PKT_Init, 0, dataInit)
	if err != nil {
		log.Error("Pack error: %s", err.Error())
		return
	}

	b, err := initPkt.Serialize()
	if err != nil {
		log.Error("Serialize error: %s", err.Error())
	}
	log.Debug(string(initPkt.Data))
	conn.Write(b)

	go func() {
		timer := time.NewTicker(20 * time.Second)
		hbPkt, _ := packet.Pack(packet.PKT_Heartbeat, 0, nil)
		heartbeat, _ := hbPkt.Serialize()
		for {
			select {
			//case <- done:
			//	break
			case pkt := <-this.outPkt:
				b, err := pkt.Serialize()
				if err != nil {
					log.Errorf("Serialize error: %s", err.Error())
				}
				log.Debugf("Write data: %s\n", b)
				conn.Write(b)
			case <-timer.C:
				conn.Write(heartbeat)
			}
		}
	}()

	var bufHeader = make([]byte, packet.PKT_HEADER_SIZE)
	for {
		//// check if we are exiting
		//select {
		//case <-this.exitChan:
		//	log.Printf("Closing connection from %s.\n", conn.RemoteAddr().String())
		//	return
		//default:
		//	// continue read
		//}

		const readTimeout = 300 * time.Second
		conn.SetReadDeadline(time.Now().Add(readTimeout))

		// read the packet header
		nbytes, err := io.ReadFull(conn, bufHeader)
		if err != nil {
			if err == io.EOF {
				log.Warn("read EOF, closing connection")
				return
			} else if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
				// just read timeout, not an error
				continue
			}
			log.Errorf("read error: %s\n", err.Error())
			return
		}
		log.Debugf("%d bytes packet header read\n", nbytes)

		var pkt = packet.Pkt{
			Data: nil,
		}
		pkt.Header.Deserialize(bufHeader)

		// read the packet data
		if pkt.Header.Len > 0 {
			log.Debugf("expecting data size: %d\n", pkt.Header.Len)
			var bufData = make([]byte, pkt.Header.Len)
			nbytes, err := io.ReadFull(conn, bufData)
			if err != nil {
				if err == io.EOF {
					log.Warn("read EOF, closing connection")
					return
				} else if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
					// read timeout
					//TODO: exit?
					log.Errorf("Timeout on receiving packet data. error: %s\n", err.Error())
					continue
				}
				log.Errorf("Error on receiving packet data. error: %s\n", err.Error())
				return
			}
			log.Debugf("%d bytes packet data read: %s\n", nbytes, bufData)
			pkt.Data = bufData
		}

		this.handlePacket(&pkt)
	}
}
Ejemplo n.º 2
0
func (this *TcpServer) handleConn(conn *net.TCPConn) {
	this.waitGroup.Add(1)
	log.Printf("New conn accepted from %s\n", conn.RemoteAddr().String())
	var (
		client *Client = nil
	)

	var bufHeader = make([]byte, packet.PKT_HEADER_SIZE)
	for {
		// check if we are exiting
		select {
		case <-this.exitChan:
			log.Printf("Closing connection from %s.\n", conn.RemoteAddr().String())
			goto Out
		default:
			// continue read
		}

		const readTimeout = 30 * time.Second
		conn.SetReadDeadline(time.Now().Add(readTimeout))

		// read the packet header
		nbytes, err := io.ReadFull(conn, bufHeader)
		if err != nil {
			if err == io.EOF {
				log.Printf("read EOF, closing connection")
				goto Out
			} else if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
				// just read timeout, not an error
				continue
			}
			log.Printf("read error: %s\n", err.Error())
			continue
		}
		log.Printf("%d bytes packet header read\n", nbytes)

		var pkt = packet.Pkt{
			Data: nil,
		}
		pkt.Header.Deserialize(bufHeader)

		// read the packet data
		if pkt.Header.Len > 0 {
			log.Printf("expecting data size: %d\n", pkt.Header.Len)
			//FIXME: check the Len
			var bufData = make([]byte, pkt.Header.Len)
			nbytes, err := io.ReadFull(conn, bufData)
			if err != nil {
				if err == io.EOF {
					log.Printf("read EOF, closing connection")
					goto Out
				} else if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
					// read timeout
					//TODO
					log.Printf("read error: %s\n", err.Error())
					continue
				}
				log.Printf("read error: %s\n", err.Error())
				continue
			}
			log.Printf("%d bytes packet data read: %s\n", nbytes, bufData)
			pkt.Data = bufData
		}

		if pkt.Header.Type == packet.PKT_Init {
			client = HandleInit(conn, &pkt)
			if client == nil {
				goto Out
			}
		} else {
			this.handlePacket(client, &pkt)
		}
	}

Out:
	conn.Close()
	if client != nil {
		ClientMapLock.Lock()
		delete(ClientMap, client.Id)
		ClientMapLock.Unlock()
	}
	this.waitGroup.Done()
}