croc/src/comm/comm.go

126 lines
2.7 KiB
Go
Raw Normal View History

2018-09-23 21:34:29 +02:00
package comm
import (
"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:43:38 +02:00
connection net.Conn
writer *bufio.Writer
2018-09-26 19:43:38 +02:00
reader *bufio.Reader
2018-09-23 21:34:29 +02:00
}
// New returns a new comm
2018-09-26 19:43:38 +02:00
func New(n net.Conn) *Comm {
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))
2018-09-26 19:43:38 +02:00
c.writer = bufio.NewWriter(n)
2018-09-26 19:54:11 +02:00
// c.connection = bufio.NewReader(n)
return c
2018-09-23 21:34:29 +02:00
}
2018-09-26 19:03:13 +02:00
// Connection returns the net.TCPConn connection
2018-09-26 19:43:38 +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
func (c *Comm) Close() {
2018-09-25 01:10:04 +02:00
c.connection.Close()
}
func (c *Comm) Write(b []byte) (int, error) {
2018-09-26 20:11:19 +02:00
c.connection.Write([]byte(fmt.Sprintf("%0.6d", len(b))))
n, err := c.connection.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 20:11:19 +02:00
// if err == nil {
// c.writer.Flush()
// }
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 19:09:11 +02:00
// func (c *Comm) Flush() {
// c.connection.Flush()
// }
2018-09-26 16:53:46 +02:00
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-26 19:53:47 +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-26 19:53:47 +02:00
n, err := c.connection.Read(tmp)
2018-09-24 16:51:24 +02:00
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
}