mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 01:44:37 +00:00
* Implement dial, support IPv6 in httpclient Added ``dial`` procedure to networking modules: ``net``, ``asyncdispatch``, ``asyncnet``. It merges socket creation, address resolution, and connection into single step. When using ``dial``, you don't have to worry about IPv4 vs IPv6 problem. Fixed addrInfo loop in connect to behave properly. Previously it would stop on first non-immediate failure, instead of continuing and trying the remaining addresses. Fixed newAsyncNativeSocket to raise proper error if socket creation fails. Fixes: #3811 * Check domain during connect() only on non-Windows This is how it was in the previous implementation of connect(). * Call 'osLastError' before 'close' in net.dial * Record osLastError before freeAddrInfo in net.dial * Add missing docs for 'dial' proc * Optimize dial to create one FD per domain, add tests And make async IPv6 servers work on Windows. * Add IPv6 test to uri module * Fix getAddrString error handling
54 lines
1.4 KiB
Nim
54 lines
1.4 KiB
Nim
discard """
|
|
file: "tasyncdial.nim"
|
|
output: '''
|
|
OK AF_INET
|
|
OK AF_INET6
|
|
'''
|
|
"""
|
|
|
|
import
|
|
nativesockets, os, asyncdispatch
|
|
|
|
proc setupServerSocket(hostname: string, port: Port, domain: Domain): AsyncFD =
|
|
## Creates a socket, binds it to the specified address, and starts listening for connecitons.
|
|
## Registers the descriptor with the dispatcher of the current thread
|
|
## Raises OSError in case of an error.
|
|
let fd = newNativeSocket(domain)
|
|
setSockOptInt(fd, SOL_SOCKET, SO_REUSEADDR, 1)
|
|
var aiList = getAddrInfo(hostname, port, domain)
|
|
if bindAddr(fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32:
|
|
freeAddrInfo(aiList)
|
|
raiseOSError(osLastError())
|
|
freeAddrInfo(aiList)
|
|
if listen(fd) != 0:
|
|
raiseOSError(osLastError())
|
|
setBlocking(fd, false)
|
|
result = fd.AsyncFD
|
|
register(result)
|
|
|
|
proc doTest(domain: static[Domain]) {.async.} =
|
|
const
|
|
testHost = when domain == Domain.AF_INET6: "::1" else: "127.0.0.1"
|
|
testPort = Port(17384)
|
|
let serverFd = setupServerSocket(testHost, testPort, domain)
|
|
let acceptFut = serverFd.accept()
|
|
let clientFdFut = dial(testHost, testPort)
|
|
|
|
let serverClientFd = await acceptFut
|
|
serverFd.closeSocket()
|
|
|
|
let clientFd = await clientFdFut
|
|
|
|
let recvFut = serverClientFd.recv(2)
|
|
await clientFd.send("Hi")
|
|
let msg = await recvFut
|
|
|
|
serverClientFd.closeSocket()
|
|
clientFd.closeSocket()
|
|
|
|
if msg == "Hi":
|
|
echo "OK ", domain
|
|
|
|
waitFor(doTest(Domain.AF_INET))
|
|
waitFor(doTest(Domain.AF_INET6))
|