func (client *Client) Recv() (communication.Command, error) {
	var cmd communication.Command
	log.Debugf("Waiting for incomming data")
	var rw *bufio.ReadWriter
	if client.Session.Connector.TLSConn == nil {
		rw = bufio.NewReadWriter(bufio.NewReader(client.Session.Connector.Conn), bufio.NewWriter(client.Session.Connector.Conn))
	} else {
		rw = bufio.NewReadWriter(bufio.NewReader(client.Session.Connector.TLSConn), bufio.NewWriter(client.Session.Connector.TLSConn))
	}
	err := gob.NewDecoder(rw).Decode(&cmd)
	if err == io.EOF {
		return communication.Command{}, err
	}
	if err != nil {
		return communication.Command{}, errors.New("Could not decode received message : " + err.Error())
	}
	log.Debugf("Received command %+v", cmd)
	_, ok := client.Session.Modules[cmd.Name]
	if !ok {
		return communication.Command{}, errors.New("Unsupported (or unknown) command : " + cmd.Name)
	}
	return cmd, nil
}
Recv read the incomming data from the server. The server use the communication.Command struct.
package client
import (
	"bufio"
	"crypto/rand"
	"crypto/sha1"
	"crypto/tls"
	"encoding/gob"
	"fmt"
	"io"
	"net"
	"time"
	"github.com/netm4ul/netm4ul/core/communication"
	"github.com/netm4ul/netm4ul/core/requirements"
	"github.com/netm4ul/netm4ul/core/session"
	"github.com/netm4ul/netm4ul/modules"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
)
const (
	maxRetry          = 10
	delayBetweenTries = 3 * time.Second
)
type Client struct {
	Session *session.Session
	ListModule []string
	ListModuleEnabled []string
}
func CreateClient(s *session.Session) *Client {
	client := Client{Session: s}
	client.InitModule()
	return &client
}
func (client *Client) Start() {
	var err error
	log.Info("Modules enabled :", client.ListModuleEnabled)
	for tries := 0; tries < maxRetry; tries++ {
		err = client.Connect()
		if err == nil {
			break
		}
		log.Errorf("Could not connect : %+v", err)
		log.Errorf("Retry count : %d, Max retries : %d", tries, maxRetry)
		time.Sleep(delayBetweenTries)
	}
	if err != nil {
		log.Fatal(err)
	}
	err = client.SendHello()
	if err != nil {
		log.Fatal(err)
	}
	go client.handleData()
}
func (client *Client) handleData() {
	for {
		cmd, err := client.Recv()
		if err == io.EOF {
			log.Fatalf("Connection closed : %s", err.Error())
		}
		if err != nil {
			log.Error(err.Error())
			continue
		}
		module, exist := client.Session.Modules[cmd.Name]
		if !exist {
			continue
		}
		go func() {
			_, err = client.Execute(module, cmd)
			if err != nil {
				log.Error("Could not execute module : " + err.Error())
			}
		}()
	}
}
func (client *Client) Connect() error {
	var err error
	ipport := client.Session.GetServerIPPort()
	if client.Session.Config.TLSParams.UseTLS {
		client.Session.Connector.TLSConn, err = tls.Dial("tcp", ipport, client.Session.Config.TLSParams.TLSConfig)
	} else {
		client.Session.Connector.Conn, err = net.Dial("tcp", ipport)
	}
	if err != nil {
		return errors.Wrap(err, "Dialing "+ipport+" failed")
	}
	return nil
}
func (client *Client) InitModule() {
	log.Debugf("Session client : %+v", client.Session)
	for m := range client.Session.Config.Modules {
		client.ListModule = append(client.ListModule, m)
		if client.Session.Config.Modules[m].Enabled {
			client.ListModuleEnabled = append(client.ListModuleEnabled, m)
		}
	}
}
func (client *Client) SendHello() error {
	var rw *bufio.ReadWriter
	if client.Session.Connector.TLSConn == nil {
		rw = bufio.NewReadWriter(bufio.NewReader(client.Session.Connector.Conn), bufio.NewWriter(client.Session.Connector.Conn))
	} else {
		rw = bufio.NewReadWriter(bufio.NewReader(client.Session.Connector.TLSConn), bufio.NewWriter(client.Session.Connector.TLSConn))
	}
	compcap, err := requirements.GetCPUCapacity()
	if err != nil {
		log.Errorf("Couldn't get the CPU Stats : %s", err.Error())
	}
	memcap, err := requirements.GetMemoryCapacity()
	if err != nil {
		log.Errorf("Couldn't get the Memory Stats : %s", err.Error())
	}
	req := requirements.Requirements{
		ComputingCapacity: compcap,
		MemoryCapacity:    memcap,
		NetworkCapacity:   requirements.CapacityMedium,   
		NetworkType:       requirements.NetworkExternal,  
	}
	token := make([]byte, 5)
	rand.Read(token)
	sha := fmt.Sprintf("%x", sha1.Sum(token))
	log.Info("New node ID : ", sha)
	node := communication.Node{
		ID:           sha,
		Modules:      client.ListModuleEnabled,
		Project:      client.Session.Config.Project.Name,
		Requirements: req,
		IsAvailable:  true,
	}
	log.Debugf("Node : %+v", node)
	err = gob.NewEncoder(rw).Encode(node)
	if err != nil {
		return err
	}
	err = rw.Flush()
	if err != nil {
		return err
	}
	return nil
}