Ejemplo n.º 1
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()
}
Ejemplo n.º 2
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.º 3
0
func HandleInit(conn *net.TCPConn, pkt *packet.Pkt) *Client {
	log.Printf("Handling packet type: Regist")
	var dataInit = packet.PktDataInit{}
	err := packet.Unpack(pkt, &dataInit)
	if err != nil {
		log.Printf("Failed to Unpack: %s", err.Error())
		return nil
	}

	// TODO: check if the Id already exist

	client := Client{
		Conn:          conn,
		Id:            dataInit.DevId,
		PktChan:       make(chan *packet.Pkt),
		LastHeartbeat: time.Now(),
	}

	log.Printf("New Device is online, Id: %s", client.Id)

	go func() {
		for {
			select {
			case pkt := <-client.PktChan:
				log.Printf("pkt to send")
				b, err := pkt.Serialize()
				if err != nil {
					log.Printf("Error on serializing pkt: %s", err.Error())
					continue
				}
				var n int
				n, err = conn.Write(b)
				if err != nil {
					log.Printf("Error on sending pkt: %s", err.Error())
					continue
				}
				log.Printf("Write successfully: %d", n)
			}
		}
	}()

	// send Response for the Init packet
	dataInitResp := packet.PktDataInitResp{
		Result: 0,
	}

	initRespPkt, err := packet.Pack(packet.PKT_Init_Resp, 0, &dataInitResp)
	if err != nil {
		log.Printf("Pack error: %s", err.Error())
		return nil
	}

	b, err := initRespPkt.Serialize()
	if err != nil {
		log.Printf("Serialize error: %s", err.Error())
		return nil
	}
	conn.Write(b)

	ClientMapLock.Lock()
	ClientMap[client.Id] = &client
	ClientMapLock.Unlock()

	return &client
}