name lookup for sockets module
This commit is contained in:
parent
324b1e9d21
commit
0bcdab8395
5 changed files with 129 additions and 35 deletions
|
|
@ -124,6 +124,16 @@ when defined(Posix):
|
||||||
of IPPROTO_ICMP: result = posix.IPPROTO_ICMP
|
of IPPROTO_ICMP: result = posix.IPPROTO_ICMP
|
||||||
else: nil
|
else: nil
|
||||||
|
|
||||||
|
else:
|
||||||
|
proc toInt(domain: TDomain): cint =
|
||||||
|
result = toU16(ord(domain))
|
||||||
|
|
||||||
|
proc ToInt(typ: TType): cint =
|
||||||
|
result = cint(ord(typ))
|
||||||
|
|
||||||
|
proc ToInt(p: TProtocol): cint =
|
||||||
|
result = cint(ord(p))
|
||||||
|
|
||||||
proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM,
|
proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM,
|
||||||
protocol: TProtocol = IPPROTO_TCP): TSocket =
|
protocol: TProtocol = IPPROTO_TCP): TSocket =
|
||||||
## creates a new socket; returns `InvalidSocket` if an error occurs.
|
## creates a new socket; returns `InvalidSocket` if an error occurs.
|
||||||
|
|
@ -242,20 +252,39 @@ proc setSockOptInt*(socket: TSocket, level, optname, optval: int) =
|
||||||
proc connect*(socket: TSocket, name: string, port = TPort(0),
|
proc connect*(socket: TSocket, name: string, port = TPort(0),
|
||||||
af: TDomain = AF_INET) =
|
af: TDomain = AF_INET) =
|
||||||
## well-known connect operation. Already does ``htons`` on the port number,
|
## well-known connect operation. Already does ``htons`` on the port number,
|
||||||
## so you shouldn't do it.
|
## so you shouldn't do it. `name` can be an IP address or a host name of the
|
||||||
var s: TSockAddrIn
|
## form "force7.de".
|
||||||
s.sin_addr.s_addr = inet_addr(name)
|
var hints: TAddrInfo
|
||||||
s.sin_port = sockets.htons(int16(port))
|
var aiList: ptr TAddrInfo = nil
|
||||||
when defined(windows):
|
hints.ai_family = toInt(af)
|
||||||
s.sin_family = toU16(ord(af))
|
hints.ai_socktype = toInt(SOCK_STREAM)
|
||||||
else:
|
hints.ai_protocol = toInt(IPPROTO_TCP)
|
||||||
case af
|
if getAddrInfo(name, $port, addr(hints), aiList) != 0'i32: OSError()
|
||||||
of AF_UNIX: s.sin_family = posix.AF_UNIX
|
# try all possibilities:
|
||||||
of AF_INET: s.sin_family = posix.AF_INET
|
var success = false
|
||||||
of AF_INET6: s.sin_family = posix.AF_INET6
|
var it = aiList
|
||||||
else: nil
|
while it != nil:
|
||||||
if connect(cint(socket), cast[ptr TSockAddr](addr(s)), sizeof(s)) < 0'i32:
|
if connect(cint(socket), it.ai_addr, it.ai_addrlen) == 0'i32:
|
||||||
OSError()
|
success = true
|
||||||
|
break
|
||||||
|
it = it.ai_next
|
||||||
|
freeaddrinfo(aiList)
|
||||||
|
if not success: OSError()
|
||||||
|
|
||||||
|
when false:
|
||||||
|
var s: TSockAddrIn
|
||||||
|
s.sin_addr.s_addr = inet_addr(name)
|
||||||
|
s.sin_port = sockets.htons(int16(port))
|
||||||
|
when defined(windows):
|
||||||
|
s.sin_family = toU16(ord(af))
|
||||||
|
else:
|
||||||
|
case af
|
||||||
|
of AF_UNIX: s.sin_family = posix.AF_UNIX
|
||||||
|
of AF_INET: s.sin_family = posix.AF_INET
|
||||||
|
of AF_INET6: s.sin_family = posix.AF_INET6
|
||||||
|
else: nil
|
||||||
|
if connect(cint(socket), cast[ptr TSockAddr](addr(s)), sizeof(s)) < 0'i32:
|
||||||
|
OSError()
|
||||||
|
|
||||||
#proc recvfrom*(s: TWinSocket, buf: cstring, len, flags: cint,
|
#proc recvfrom*(s: TWinSocket, buf: cstring, len, flags: cint,
|
||||||
# fromm: ptr TSockAddr, fromlen: ptr cint): cint
|
# fromm: ptr TSockAddr, fromlen: ptr cint): cint
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,8 @@ const
|
||||||
INADDR_BROADCAST* = -1
|
INADDR_BROADCAST* = -1
|
||||||
INADDR_NONE* = -1
|
INADDR_NONE* = -1
|
||||||
|
|
||||||
|
ws2dll = "Ws2_32.dll"
|
||||||
|
|
||||||
type
|
type
|
||||||
TWSAData* {.pure, final.} = object
|
TWSAData* {.pure, final.} = object
|
||||||
wVersion, wHighVersion: int16
|
wVersion, wHighVersion: int16
|
||||||
|
|
@ -270,62 +272,79 @@ type
|
||||||
|
|
||||||
TTimeval* {.pure, final.} = object
|
TTimeval* {.pure, final.} = object
|
||||||
tv_sec*, tv_usec*: int32
|
tv_sec*, tv_usec*: int32
|
||||||
|
|
||||||
|
TAddrInfo* {.pure, final.} = object
|
||||||
|
ai_flags*: cint ## Input flags.
|
||||||
|
ai_family*: cint ## Address family of socket.
|
||||||
|
ai_socktype*: cint ## Socket type.
|
||||||
|
ai_protocol*: cint ## Protocol of socket.
|
||||||
|
ai_addrlen*: int ## Length of socket address.
|
||||||
|
ai_canonname*: cstring ## Canonical name of service location.
|
||||||
|
ai_addr*: ptr TSockAddr ## Socket address of socket.
|
||||||
|
ai_next*: ptr TAddrInfo ## Pointer to next in list.
|
||||||
|
|
||||||
|
Tsocklen* = cint
|
||||||
|
|
||||||
proc getservbyname*(name, proto: cstring): ptr TServent {.
|
proc getservbyname*(name, proto: cstring): ptr TServent {.
|
||||||
stdcall, importc: "getservbyname", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "getservbyname", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc getservbyport*(port: cint, proto: cstring): ptr TServent {.
|
proc getservbyport*(port: cint, proto: cstring): ptr TServent {.
|
||||||
stdcall, importc: "getservbyport", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "getservbyport", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc gethostbyname*(name: cstring): ptr THostEnt {.
|
proc gethostbyname*(name: cstring): ptr THostEnt {.
|
||||||
stdcall, importc: "gethostbyname", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "gethostbyname", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc socket*(af, typ, protocol: cint): TWinSocket {.
|
proc socket*(af, typ, protocol: cint): TWinSocket {.
|
||||||
stdcall, importc: "socket", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "socket", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc closesocket*(s: TWinSocket): cint {.
|
proc closesocket*(s: TWinSocket): cint {.
|
||||||
stdcall, importc: "closesocket", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "closesocket", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc accept*(s: TWinSocket, a: ptr TSockAddr, addrlen: ptr cint): TWinSocket {.
|
proc accept*(s: TWinSocket, a: ptr TSockAddr, addrlen: ptr cint): TWinSocket {.
|
||||||
stdcall, importc: "accept", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "accept", dynlib: ws2dll.}
|
||||||
proc bindSocket*(s: TWinSocket, name: ptr TSockAddr, namelen: cint): cint {.
|
proc bindSocket*(s: TWinSocket, name: ptr TSockAddr, namelen: cint): cint {.
|
||||||
stdcall, importc: "bind", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "bind", dynlib: ws2dll.}
|
||||||
proc connect*(s: TWinSocket, name: ptr TSockAddr, namelen: cint): cint {.
|
proc connect*(s: TWinSocket, name: ptr TSockAddr, namelen: cint): cint {.
|
||||||
stdcall, importc: "connect", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "connect", dynlib: ws2dll.}
|
||||||
proc getsockname*(s: TWinSocket, name: ptr TSockAddr,
|
proc getsockname*(s: TWinSocket, name: ptr TSockAddr,
|
||||||
namelen: ptr cint): cint {.
|
namelen: ptr cint): cint {.
|
||||||
stdcall, importc: "getsockname", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "getsockname", dynlib: ws2dll.}
|
||||||
proc getsockopt*(s: TWinSocket, level, optname: cint, optval: pointer,
|
proc getsockopt*(s: TWinSocket, level, optname: cint, optval: pointer,
|
||||||
optlen: ptr cint): cint {.
|
optlen: ptr cint): cint {.
|
||||||
stdcall, importc: "getsockopt", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "getsockopt", dynlib: ws2dll.}
|
||||||
proc setsockopt*(s: TWinSocket, level, optname: cint, optval: pointer,
|
proc setsockopt*(s: TWinSocket, level, optname: cint, optval: pointer,
|
||||||
optlen: cint): cint {.
|
optlen: cint): cint {.
|
||||||
stdcall, importc: "setsockopt", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "setsockopt", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc listen*(s: TWinSocket, backlog: cint): cint {.
|
proc listen*(s: TWinSocket, backlog: cint): cint {.
|
||||||
stdcall, importc: "listen", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "listen", dynlib: ws2dll.}
|
||||||
proc recv*(s: TWinSocket, buf: pointer, len, flags: cint): cint {.
|
proc recv*(s: TWinSocket, buf: pointer, len, flags: cint): cint {.
|
||||||
stdcall, importc: "recv", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "recv", dynlib: ws2dll.}
|
||||||
proc recvfrom*(s: TWinSocket, buf: cstring, len, flags: cint,
|
proc recvfrom*(s: TWinSocket, buf: cstring, len, flags: cint,
|
||||||
fromm: ptr TSockAddr, fromlen: ptr cint): cint {.
|
fromm: ptr TSockAddr, fromlen: ptr cint): cint {.
|
||||||
stdcall, importc: "recvfrom", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "recvfrom", dynlib: ws2dll.}
|
||||||
proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet,
|
proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet,
|
||||||
timeout: ptr TTimeval): cint {.
|
timeout: ptr TTimeval): cint {.
|
||||||
stdcall, importc: "select", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "select", dynlib: ws2dll.}
|
||||||
proc send*(s: TWinSocket, buf: pointer, len, flags: cint): cint {.
|
proc send*(s: TWinSocket, buf: pointer, len, flags: cint): cint {.
|
||||||
stdcall, importc: "send", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "send", dynlib: ws2dll.}
|
||||||
proc sendto*(s: TWinSocket, buf: cstring, len, flags: cint,
|
proc sendto*(s: TWinSocket, buf: cstring, len, flags: cint,
|
||||||
to: ptr TSockAddr, tolen: cint): cint {.
|
to: ptr TSockAddr, tolen: cint): cint {.
|
||||||
stdcall, importc: "sendto", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "sendto", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc shutdown*(s: TWinSocket, how: cint): cint {.
|
proc shutdown*(s: TWinSocket, how: cint): cint {.
|
||||||
stdcall, importc: "shutdown", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "shutdown", dynlib: ws2dll.}
|
||||||
|
|
||||||
|
proc getnameinfo*(a1: ptr Tsockaddr, a2: Tsocklen,
|
||||||
|
a3: cstring, a4: Tsocklen, a5: cstring,
|
||||||
|
a6: Tsocklen, a7: cint): cint {.
|
||||||
|
stdcall, importc: "getnameinfo", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc inet_addr*(cp: cstring): int32 {.
|
proc inet_addr*(cp: cstring): int32 {.
|
||||||
stdcall, importc: "inet_addr", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "inet_addr", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc WSAFDIsSet(s: TWinSocket, FDSet: var TFDSet): bool {.
|
proc WSAFDIsSet(s: TWinSocket, FDSet: var TFDSet): bool {.
|
||||||
stdcall, importc: "__WSAFDIsSet", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll.}
|
||||||
|
|
||||||
proc FD_ISSET*(Socket: TWinSocket, FDSet: var TFDSet): cint =
|
proc FD_ISSET*(Socket: TWinSocket, FDSet: var TFDSet): cint =
|
||||||
result = if WSAFDIsSet(Socket, FDSet): 1'i32 else: 0'i32
|
result = if WSAFDIsSet(Socket, FDSet): 1'i32 else: 0'i32
|
||||||
|
|
@ -339,5 +358,13 @@ proc FD_ZERO*(FDSet: var TFDSet) =
|
||||||
FDSet.fd_count = 0
|
FDSet.fd_count = 0
|
||||||
|
|
||||||
proc WSAStartup*(wVersionRequired: int16, WSData: var TWSAData): cint {.
|
proc WSAStartup*(wVersionRequired: int16, WSData: var TWSAData): cint {.
|
||||||
stdcall, importc: "WSAStartup", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "WSAStartup", dynlib: ws2dll.}
|
||||||
|
|
||||||
|
proc getaddrinfo*(nodename, servname: cstring, hints: ptr TAddrInfo,
|
||||||
|
res: var ptr TAddrInfo): cint {.
|
||||||
|
stdcall, importc: "getaddrinfo", dynlib: ws2dll.}
|
||||||
|
|
||||||
|
proc freeaddrinfo*(ai: ptr TAddrInfo) {.
|
||||||
|
stdcall, importc: "freeaddrinfo", dynlib: ws2dll.}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
3
tests/tparsefloat.nim
Executable file
3
tests/tparsefloat.nim
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
echo ParseFloat("5000") / ParseFloat("10")
|
||||||
24
tests/tquicksort.nim
Executable file
24
tests/tquicksort.nim
Executable file
|
|
@ -0,0 +1,24 @@
|
||||||
|
proc QuickSort(list: seq[int]): seq[int] =
|
||||||
|
if len(list) == 0:
|
||||||
|
return @[]
|
||||||
|
var pivot = list[0]
|
||||||
|
var left: seq[int] = @[]
|
||||||
|
var right: seq[int] = @[]
|
||||||
|
for i in low(list)..high(list):
|
||||||
|
if list[i] < pivot:
|
||||||
|
left.add(list[i])
|
||||||
|
elif list[i] > pivot:
|
||||||
|
right.add(list[i])
|
||||||
|
result = QuickSort(left) & pivot & QuickSort(right)
|
||||||
|
|
||||||
|
proc echoSeq(a: seq[int]) =
|
||||||
|
for i in low(a)..high(a):
|
||||||
|
echo(a[i])
|
||||||
|
|
||||||
|
var
|
||||||
|
list: seq[int]
|
||||||
|
|
||||||
|
list = QuickSort(@[89,23,15,23,56,123,356,12,7,1,6,2,9,4,3])
|
||||||
|
echoSeq(list)
|
||||||
|
|
||||||
|
|
||||||
11
tests/tsockets.nim
Executable file
11
tests/tsockets.nim
Executable file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import sockets
|
||||||
|
var s: TSocket
|
||||||
|
s = socket()
|
||||||
|
|
||||||
|
s.connect("www.google.com", TPort(80))
|
||||||
|
|
||||||
|
var recvData: string = ""
|
||||||
|
echo(s.recvLine(recvData))
|
||||||
|
echo(recvData)
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue