croc/src/comm/comm.go

123 lines
2.6 KiB
Go
Raw Normal View History

2018-09-23 21:34:29 +02:00
package comm
import (
2018-09-23 21:50:03 +02:00
"bytes"
2019-04-27 18:20:03 +02:00
"encoding/binary"
2018-09-23 23:00:31 +02:00
"fmt"
2018-09-23 21:34:29 +02:00
"net"
2018-09-23 22:32:46 +02:00
"time"
2018-10-13 15:09:55 +02:00
"github.com/pkg/errors"
2018-09-23 21:34:29 +02:00
)
// Comm is some basic TCP communication
type Comm struct {
2018-09-26 19:43:38 +02:00
connection net.Conn
2018-09-23 21:34:29 +02:00
}
2019-04-27 18:20:03 +02:00
// NewConnection gets a new comm to a tcp address
func NewConnection(address string, timelimit ...time.Duration) (c *Comm, err error) {
tlimit := 30 * time.Second
if len(timelimit) > 0 {
tlimit = timelimit[0]
}
connection, err := net.DialTimeout("tcp", address, tlimit)
2019-04-27 18:20:03 +02:00
if err != nil {
return
}
c = New(connection)
return
}
2018-09-23 21:34:29 +02:00
// New returns a new comm
2019-04-29 22:06:18 +02:00
func New(c net.Conn) *Comm {
2018-09-26 23:31:45 +02:00
c.SetReadDeadline(time.Now().Add(3 * time.Hour))
c.SetDeadline(time.Now().Add(3 * time.Hour))
2018-10-10 06:16:26 +02:00
c.SetWriteDeadline(time.Now().Add(3 * time.Hour))
2019-04-29 22:06:18 +02:00
comm := new(Comm)
comm.connection = c
return comm
2018-09-23 21:34:29 +02:00
}
2018-09-26 23:31:45 +02:00
// Connection returns the net.Conn connection
2019-04-29 22:06:18 +02:00
func (c *Comm) Connection() net.Conn {
2018-09-23 21:34:29 +02:00
return c.connection
}
2018-09-25 01:10:04 +02:00
// Close closes the connection
2019-04-29 22:06:18 +02:00
func (c *Comm) Close() {
2018-09-25 01:10:04 +02:00
c.connection.Close()
}
2019-04-29 22:06:18 +02:00
func (c *Comm) Write(b []byte) (int, error) {
2019-04-27 18:20:03 +02:00
header := new(bytes.Buffer)
err := binary.Write(header, binary.LittleEndian, uint32(len(b)))
if err != nil {
fmt.Println("binary.Write failed:", err)
}
tmpCopy := append(header.Bytes(), b...)
2018-10-10 04:36:59 +02:00
n, err := c.connection.Write(tmpCopy)
if n != len(tmpCopy) {
2018-10-13 15:09:55 +02:00
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("wanted to write %d but wrote %d", len(b), n))
} else {
err = fmt.Errorf("wanted to write %d but wrote %d", len(b), n)
}
2018-09-23 23:00:31 +02:00
}
2018-09-23 23:12:45 +02:00
// log.Printf("wanted to write %d but wrote %d", n, len(b))
2018-09-23 21:50:03 +02:00
return n, err
2018-09-23 21:34:29 +02:00
}
2019-04-29 22:06:18 +02:00
func (c *Comm) Read() (buf []byte, numBytes int, bs []byte, err error) {
2019-04-30 16:07:07 +02:00
// read until we get 4 bytes for the header
var header []byte
numBytes = 4
for {
2019-05-01 20:08:24 +02:00
tmp := make([]byte, numBytes-len(header))
2019-04-30 16:07:07 +02:00
n, errRead := c.connection.Read(tmp)
if errRead != nil {
err = errRead
return
}
header = append(header, tmp[:n]...)
if numBytes == len(header) {
break
}
2018-09-23 23:15:23 +02:00
}
2018-09-24 16:51:24 +02:00
2019-04-27 18:20:03 +02:00
var numBytesUint32 uint32
rbuf := bytes.NewReader(header)
err = binary.Read(rbuf, binary.LittleEndian, &numBytesUint32)
2018-09-23 23:15:23 +02:00
if err != nil {
2019-04-27 18:20:03 +02:00
fmt.Println("binary.Read failed:", err)
2018-09-23 23:12:45 +02:00
}
2019-04-27 18:20:03 +02:00
numBytes = int(numBytesUint32)
2019-05-01 20:08:24 +02:00
buf = make([]byte, 0)
2018-09-23 21:50:03 +02:00
for {
2019-04-30 15:57:45 +02:00
// log.Debugf("bytes: %d/%d",len(buf),numBytes)
tmp := make([]byte, numBytes-len(buf))
2019-04-27 18:20:03 +02:00
n, errRead := c.connection.Read(tmp)
if errRead != nil {
err = errRead
return
2018-09-23 21:50:03 +02:00
}
2019-04-27 18:20:03 +02:00
buf = append(buf, tmp[:n]...)
if numBytes == len(buf) {
2018-09-23 21:50:03 +02:00
break
}
}
2018-09-23 21:34:29 +02:00
return
}
// Send a message
2019-04-29 22:06:18 +02:00
func (c *Comm) Send(message []byte) (err error) {
2019-04-27 18:20:03 +02:00
_, err = c.Write(message)
2018-09-23 21:34:29 +02:00
return
}
// Receive a message
2019-04-29 22:06:18 +02:00
func (c *Comm) Receive() (b []byte, err error) {
2019-04-27 18:20:03 +02:00
b, _, _, err = c.Read()
2018-09-23 21:34:29 +02:00
return
}