-
Notifications
You must be signed in to change notification settings - Fork 96
/
Copy pathudp.go
102 lines (78 loc) · 2.26 KB
/
udp.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package modbus
import (
"net"
"time"
)
// udpSockWrapper wraps a net.UDPConn (UDP socket) to
// allow transports to consume data off the network socket on
// a byte per byte basis rather than datagram by datagram.
type udpSockWrapper struct {
leftoverCount int
rxbuf []byte
sock *net.UDPConn
}
func newUDPSockWrapper(sock net.Conn) (usw *udpSockWrapper) {
usw = &udpSockWrapper{
rxbuf: make([]byte, maxTCPFrameLength),
sock: sock.(*net.UDPConn),
}
return
}
func (usw *udpSockWrapper) Read(buf []byte) (rlen int, err error) {
var copied int
if usw.leftoverCount > 0 {
// if we're holding onto any bytes from a previous datagram,
// use them to satisfy the read (potentially partially)
copied = copy(buf, usw.rxbuf[0:usw.leftoverCount])
if usw.leftoverCount > copied {
// move any leftover bytes to the beginning of the buffer
copy(usw.rxbuf, usw.rxbuf[copied:usw.leftoverCount])
}
// make a note of how many leftover bytes we have in the buffer
usw.leftoverCount -= copied
} else {
// read up to maxTCPFrameLength bytes from the socket
rlen, err = usw.sock.Read(usw.rxbuf)
if err != nil {
return
}
// copy as many bytes as possible to satisfy the read
copied = copy(buf, usw.rxbuf[0:rlen])
if rlen > copied {
// move any leftover bytes to the beginning of the buffer
copy(usw.rxbuf, usw.rxbuf[copied:rlen])
}
// make a note of how many leftover bytes we have in the buffer
usw.leftoverCount = rlen - copied
}
rlen = copied
return
}
func (usw *udpSockWrapper) Close() (err error) {
err = usw.sock.Close()
return
}
func (usw *udpSockWrapper) Write(buf []byte) (wlen int, err error) {
wlen, err = usw.sock.Write(buf)
return
}
func (usw *udpSockWrapper) SetDeadline(deadline time.Time) (err error) {
err = usw.sock.SetDeadline(deadline)
return
}
func (usw *udpSockWrapper) SetReadDeadline(deadline time.Time) (err error) {
err = usw.sock.SetReadDeadline(deadline)
return
}
func (usw *udpSockWrapper) SetWriteDeadline(deadline time.Time) (err error) {
err = usw.sock.SetWriteDeadline(deadline)
return
}
func (usw *udpSockWrapper) LocalAddr() (addr net.Addr) {
addr = usw.sock.LocalAddr()
return
}
func (usw *udpSockWrapper) RemoteAddr() (addr net.Addr) {
addr = usw.sock.RemoteAddr()
return
}