/
transport.go
83 lines (66 loc) · 1.64 KB
/
transport.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package goscreenmonit
import (
"encoding/binary"
"log"
"net"
)
// Helper function to read a certain amount of data into a buffer
func ReadConnBytes(count uint64, conn net.Conn) ([]byte, error) {
final := make([]byte, 0)
tmp := make([]byte, count)
// Read until all bytes are retrieved
for {
n, err := conn.Read(tmp)
if err != nil {
return nil, err
}
final = append(final, tmp[:n]...)
// All data is captured
if len(final) >= len(tmp) {
break
}
}
return final, nil
}
// Accept and process requests from other end of socket
func ReadCommand(conn net.Conn, datapipe chan []byte) {
for {
// Read first uint64 as the length of the message
lengthdata, lerr := ReadConnBytes(8, conn)
if lerr != nil {
close(datapipe)
return
}
msglen := binary.LittleEndian.Uint64(lengthdata)
// Check the length to make sure it's a valid message
if msglen > 1e9 {
log.Println("Stream sync broken, resetting connection.")
close(datapipe)
return
}
// Read the full message based on previous length
msgdata, merr := ReadConnBytes(msglen, conn)
if merr != nil {
close(datapipe)
return
}
// Send data to channel
datapipe <- msgdata
}
}
// Send a message by sending the message size before the message itself
func SendMessage(msg []byte, conn net.Conn) error {
// Create the message size data
sizemsg := make([]byte, 8)
msglen := uint64(len(msg))
binary.LittleEndian.PutUint64(sizemsg, msglen)
// First send the size of the message
if _, err := conn.Write(sizemsg); err != nil {
return err
}
// Then send the actual message
if _, err := conn.Write(msg); err != nil {
return err
}
return nil
}