2018-09-23 21:34:29 +02:00
|
|
|
package comm
|
|
|
|
|
|
|
|
import (
|
2018-09-26 16:39:45 +02:00
|
|
|
"bufio"
|
2018-09-23 21:50:03 +02:00
|
|
|
"bytes"
|
2018-09-23 23:00:31 +02:00
|
|
|
"fmt"
|
2018-09-23 21:34:29 +02:00
|
|
|
"net"
|
2018-09-23 23:15:23 +02:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2018-09-23 22:32:46 +02:00
|
|
|
"time"
|
2018-09-23 21:34:29 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// Comm is some basic TCP communication
|
|
|
|
type Comm struct {
|
2018-09-26 19:03:13 +02:00
|
|
|
connection *net.TCPConn
|
2018-09-26 16:39:45 +02:00
|
|
|
writer *bufio.Writer
|
2018-09-23 21:34:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// New returns a new comm
|
2018-09-26 19:03:13 +02:00
|
|
|
func New(n *net.TCPConn) *Comm {
|
2018-09-26 16:39:45 +02:00
|
|
|
c := new(Comm)
|
|
|
|
c.connection = n
|
|
|
|
c.connection.SetReadDeadline(time.Now().Add(3 * time.Hour))
|
|
|
|
c.connection.SetDeadline(time.Now().Add(3 * time.Hour))
|
|
|
|
c.connection.SetWriteDeadline(time.Now().Add(3 * time.Hour))
|
|
|
|
return c
|
2018-09-23 21:34:29 +02:00
|
|
|
}
|
|
|
|
|
2018-09-26 19:03:13 +02:00
|
|
|
// Connection returns the net.TCPConn connection
|
|
|
|
func (c *Comm) Connection() *net.TCPConn {
|
2018-09-23 21:34:29 +02:00
|
|
|
return c.connection
|
|
|
|
}
|
|
|
|
|
2018-09-25 01:10:04 +02:00
|
|
|
// Close closes the connection
|
2018-09-26 16:39:45 +02:00
|
|
|
func (c *Comm) Close() {
|
2018-09-25 01:10:04 +02:00
|
|
|
c.connection.Close()
|
|
|
|
}
|
|
|
|
|
2018-09-26 16:39:45 +02:00
|
|
|
func (c *Comm) Write(b []byte) (int, error) {
|
|
|
|
c.writer.Write([]byte(fmt.Sprintf("%0.6d", len(b))))
|
|
|
|
n, err := c.writer.Write(b)
|
2018-09-23 23:00:31 +02:00
|
|
|
if n != len(b) {
|
|
|
|
err = fmt.Errorf("wanted to write %d but wrote %d", n, len(b))
|
|
|
|
}
|
2018-09-26 16:39:45 +02:00
|
|
|
if err == nil {
|
2018-09-26 16:53:46 +02:00
|
|
|
c.writer.Flush()
|
2018-09-26 16:39:45 +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
|
|
|
}
|
|
|
|
|
2018-09-26 16:53:46 +02:00
|
|
|
func (c *Comm) Flush() {
|
|
|
|
c.writer.Flush()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Comm) Read() (buf []byte, numBytes int, bs []byte, err error) {
|
2018-09-26 15:57:52 +02:00
|
|
|
// read until we get 6 bytes
|
|
|
|
tmp := make([]byte, 6)
|
2018-09-24 16:51:24 +02:00
|
|
|
n, err := c.connection.Read(tmp)
|
2018-09-23 21:50:03 +02:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2018-09-24 16:51:24 +02:00
|
|
|
tmpCopy := make([]byte, n)
|
|
|
|
// Copy the buffer so it doesn't get changed while read by the recipient.
|
|
|
|
copy(tmpCopy, tmp[:n])
|
|
|
|
bs = tmpCopy
|
|
|
|
|
|
|
|
tmp = make([]byte, 1)
|
2018-09-23 23:12:45 +02:00
|
|
|
for {
|
2018-09-24 16:51:24 +02:00
|
|
|
// see if we have enough bytes
|
2018-09-24 04:24:57 +02:00
|
|
|
bs = bytes.Trim(bs, "\x00")
|
2018-09-26 15:57:52 +02:00
|
|
|
if len(bs) == 6 {
|
2018-09-23 23:12:45 +02:00
|
|
|
break
|
|
|
|
}
|
2018-09-24 16:51:24 +02:00
|
|
|
n, err := c.connection.Read(tmp)
|
|
|
|
if err != nil {
|
|
|
|
return nil, 0, nil, err
|
|
|
|
}
|
|
|
|
tmpCopy = make([]byte, n)
|
|
|
|
// Copy the buffer so it doesn't get changed while read by the recipient.
|
|
|
|
copy(tmpCopy, tmp[:n])
|
|
|
|
bs = append(bs, tmpCopy...)
|
2018-09-23 23:15:23 +02:00
|
|
|
}
|
2018-09-24 16:51:24 +02:00
|
|
|
|
2018-09-23 23:15:23 +02:00
|
|
|
numBytes, err = strconv.Atoi(strings.TrimLeft(string(bs), "0"))
|
|
|
|
if err != nil {
|
|
|
|
return nil, 0, nil, err
|
2018-09-23 23:12:45 +02:00
|
|
|
}
|
2018-09-24 17:29:54 +02:00
|
|
|
buf = []byte{}
|
2018-09-24 04:24:57 +02:00
|
|
|
tmp = make([]byte, numBytes)
|
2018-09-23 21:50:03 +02:00
|
|
|
for {
|
2018-09-24 16:51:24 +02:00
|
|
|
n, err := c.connection.Read(tmp)
|
2018-09-23 21:50:03 +02:00
|
|
|
if err != nil {
|
2018-09-24 16:51:24 +02:00
|
|
|
return nil, 0, nil, err
|
2018-09-23 21:50:03 +02:00
|
|
|
}
|
2018-09-24 17:29:54 +02:00
|
|
|
tmpCopy = make([]byte, n)
|
2018-09-24 16:51:24 +02:00
|
|
|
// Copy the buffer so it doesn't get changed while read by the recipient.
|
|
|
|
copy(tmpCopy, tmp[:n])
|
2018-09-24 17:29:54 +02:00
|
|
|
buf = append(buf, bytes.TrimRight(tmpCopy, "\x00")...)
|
|
|
|
if len(buf) < numBytes {
|
2018-09-24 16:51:24 +02:00
|
|
|
// shrink the amount we need to read
|
2018-09-24 17:29:54 +02:00
|
|
|
tmp = tmp[:numBytes-len(buf)]
|
2018-09-23 21:50:03 +02:00
|
|
|
} else {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2018-09-24 16:51:56 +02:00
|
|
|
// log.Printf("wanted %d and got %d", numBytes, len(buf))
|
2018-09-23 21:34:29 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send a message
|
2018-09-26 16:53:46 +02:00
|
|
|
func (c *Comm) Send(message string) (err error) {
|
2018-09-23 21:50:03 +02:00
|
|
|
_, err = c.Write([]byte(message))
|
2018-09-23 21:34:29 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Receive a message
|
2018-09-26 16:53:46 +02:00
|
|
|
func (c *Comm) Receive() (s string, err error) {
|
2018-09-23 23:12:45 +02:00
|
|
|
b, _, _, err := c.Read()
|
2018-09-23 21:50:03 +02:00
|
|
|
s = string(b)
|
2018-09-23 21:34:29 +02:00
|
|
|
return
|
|
|
|
}
|