-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathudp_server.nim
69 lines (55 loc) · 1.74 KB
/
udp_server.nim
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
import nimuring
from posix import Sockaddr_storage, SockLen, IOvec, Tmsghdr
import std/strformat
import net
var q = newQueue(4096, {SETUP_SQPOLL})
let server = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
const BufferSize = 4096
const Pool = 64
try:
server.bindAddr(port=Port(8000))
let (ip, port) = server.getLocalAddr()
echo fmt"listening on {ip}:{port}"
let serverFd = server.getFd
var msgs = newSeq[ptr Tmsghdr](Pool)
for i in 0..<Pool:
let buf = allocShared(BufferSize)
var iov = createShared(IOVec)
iov.iov_base = buf
iov.iov_len = BufferSize
var msg = createShared(Tmsghdr)
msg.msg_name = createShared(Sockaddr_storage)
msg.msg_namelen = sizeof(Sockaddr_storage).SockLen
msg.msg_iov = iov
msg.msg_iovlen = 1
msgs[i] = msg
q.recvmsg(i, serverFd, msg, 0)
q.submit()
while true:
var cqes = q.copyCqes(1)
for cqe in cqes:
if cqe.userData < Pool:
let prevmsg = msgs[cqe.userData]
let buf = allocShared(cqe.res)
var iov = createShared(IOVec)
iov.iov_base = buf
iov.iov_len = cqe.res.uint
copyMem(buf, prevmsg.msg_iov.iov_base, cqe.res)
let `addr` = createShared(Sockaddr_storage)
copyMem(`addr`, prevmsg.msg_name, sizeof(Sockaddr_storage))
var msg = createShared(Tmsghdr)
msg.msg_name = `addr`
msg.msg_namelen = prevmsg.msg_namelen
msg.msg_iov = iov
msg.msg_iovlen = 1
q.sendmsg(msg, serverFd, msg, 0)
q.recvmsg(cqe.userData, serverFd, prevmsg, 0)
else:
let msg = cast[ptr Tmsghdr](cqe.userData)
dealloc(msg.msg_name)
dealloc(msg.msg_iov.iov_base)
dealloc(msg)
q.submit()
finally:
# Socket has no graceful =destroy
server.close()