func (nt *NetCatClient) ReadDirect(data []byte) (n int, err error) {
	n, err = nt.conn.Read(data)
	return n, err
}
ReadDirect reads requested data from the socket directly. Use this with caution because the caller is
responsible for reading length prefix and knowing when one packet starts and ends
package net
import (
	"encoding/binary"
	"net"
	"time"
)
type MliType string
const (
	Mli2i MliType = "2i"
	Mli2e MliType = "2e"
	Mli4e MliType = "4e"
	Mli4i MliType = "4i"
)
type NetCatClient struct {
	serverAddr string
	mliType    MliType
	conn       net.Conn
}
type ReadOptions struct {
	Deadline time.Time
}
func NewNetCatClient(addr string, mliType MliType) *NetCatClient {
	var nt NetCatClient
	nt.mliType = mliType
	nt.serverAddr = addr
	return &nt
}
func (nt *NetCatClient) OpenConnection() (err error) {
	nt.conn, err = net.Dial("tcp4", nt.serverAddr)
	return err
}
func (nt *NetCatClient) Close() {
	_ = nt.conn.Close()
}
func (nt *NetCatClient) Write(data []byte) (err error) {
	dataWithMli := AddMLI(nt.mliType, data)
	_, err = nt.conn.Write(dataWithMli)
	return err
}