lib/min_net.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 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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
import net, nativesockets, strutils, critbits import ../core/types, ../core/parser, ../core/interpreter, ../core/utils # Network proc net_module*(i: In)= i.define("net") .symbol("^socket") do (i: In): var q: MinValue i.reqQuotation q # (ipv4 stream tcp) if q.qVal.len < 3 or not (q.qVal[0].isSymbol and q.qVal[1].isSymbol and q.qVal[2].isSymbol): raiseInvalid("Quotation must contain three symbols for <domain> <type> <protocol>") let vals = q.qVal if not ["ipv4", "ipv6"].contains(vals[0].symVal): raiseInvalid("Domain symbol must be 'ipv4' or 'ipv6'") if not ["stream", "dgram"].contains(vals[1].symVal): raiseInvalid("Type symbol must be 'stream' or 'dgram'") if not ["tcp", "udp"].contains(vals[2].symVal): raiseInvalid("Protocol symbol must be 'tcp' or 'udp'") var domain: Domain sockettype: SockType protocol: Protocol # Process domain if vals[0].symVal == "ipv4": domain = AF_INET else: domain = AF_INET6 if vals[1].symVal == "stream": sockettype = SOCK_STREAM else: sockettype = SOCK_DGRAM if vals[2].symVal == "tcp": protocol = IPPROTO_TCP else: protocol = IPPROTO_UDP var socket = newSocket(domain, sockettype, protocol) q.objType = "socket" q.obj = socket[].addr i.newScope("<socket>", q) q.scope .symbol("domain") do (i: In): i.push q i.push q.qVal[0].symVal.newVal .symbol("type") do (i: In): i.push q i.push q.qVal[1].symVal.newVal .symbol("protocol") do (i: In): i.push q i.push q.qVal[2].symVal.newVal .symbol("close") do (i: In): q.to(Socket).close() .symbol("listen") do (i: In): var port: MinValue i.reqInt port var socket = q.to(Socket) socket.bindAddr(Port(port.intVal)) q.qVal.add "0.0.0.0".newSym q.qVal.add port q.scope .symbol("address") do (i:In): i.push "0.0.0.0".newVal .symbol("port") do (i:In): i.push port .finalize() socket.listen() i.push q .symbol("accept") do (i: In): # Open same socket type as server i.eval "$1 net %^socket" % [$q.qVal[0..2].newVal] var clientVal: MinValue i.reqObject "socket", clientVal var client = clientVal.to(Socket) var address = "" q.to(Socket).acceptAddr(client, address) clientVal.qVal.add address.newSym i.push clientVal .symbol("connect") do (i: In): var q, address, port: MinValue i.reqInt port i.reqString address q.to(Socket).connect(address.strVal, Port(port.intVal)) q.qVal.add address.strVal.newSym q.qVal.add port q.scope .symbol("client-address") do (i:In): i.push address.strVal.newVal .symbol("client-port") do (i:In): i.push port .finalize() i.push q .symbol("send") do (i: In): var s: MinValue i.reqString s q.to(Socket).send s.strVal i.push q .symbol("recv") do (i: In): var size: MinValue i.reqInt size var s = "" discard q.to(Socket).recv(s, size.intVal.int) i.push q i.push s.newVal .symbol("recv-line") do (i: In): var s = "" q.to(Socket).readLine(s) i.push @[q] i.push s.newVal .finalize() i.push q .finalize() |