mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 18:02:05 +00:00
* fix =#13790 ptr char (+friends) should not implicitly convert to cstring * Apply suggestions from code review * first round; compiles on windows * nimPreviewSlimSystem * conversion is unsafe, cast needed * fixes more tests * fixes asyncnet * another try another error * last one * true * one more * why bugs didn't show at once * add `nimPreviewCstringConversion` switch * typo * fixes ptr to cstring warnings[backport] * add fixes Co-authored-by: xflywind <43030857+xflywind@users.noreply.github.com>
112 lines
3.7 KiB
Nim
112 lines
3.7 KiB
Nim
discard """
|
|
output: "5000"
|
|
"""
|
|
import asyncdispatch, nativesockets, net, strutils, os
|
|
|
|
when defined(windows):
|
|
import winlean
|
|
else:
|
|
import posix
|
|
|
|
var msgCount = 0
|
|
var recvCount = 0
|
|
|
|
const
|
|
messagesToSend = 100
|
|
swarmSize = 50
|
|
serverPort = 10333
|
|
|
|
var
|
|
sendports = 0
|
|
recvports = 0
|
|
|
|
proc saveSendingPort(port: int) =
|
|
sendports = sendports + port
|
|
|
|
proc saveReceivedPort(port: int) =
|
|
recvports = recvports + port
|
|
|
|
proc prepareAddress(intaddr: uint32, intport: uint16): ptr Sockaddr_in =
|
|
result = cast[ptr Sockaddr_in](alloc0(sizeof(Sockaddr_in)))
|
|
result.sin_family = typeof(result.sin_family)(toInt(nativesockets.AF_INET))
|
|
result.sin_port = nativesockets.htons(intport)
|
|
result.sin_addr.s_addr = nativesockets.htonl(intaddr)
|
|
|
|
proc launchSwarm(name: ptr SockAddr) {.async.} =
|
|
var i = 0
|
|
var k = 0
|
|
var buffer: array[16384, char]
|
|
var slen = sizeof(Sockaddr_in).SockLen
|
|
var saddr = Sockaddr_in()
|
|
while i < swarmSize:
|
|
var peeraddr = prepareAddress(INADDR_LOOPBACK, 0)
|
|
var sock = createAsyncNativeSocket(nativesockets.AF_INET,
|
|
nativesockets.SOCK_DGRAM,
|
|
Protocol.IPPROTO_UDP)
|
|
if bindAddr(sock.SocketHandle, cast[ptr SockAddr](peeraddr),
|
|
sizeof(Sockaddr_in).Socklen) < 0'i32:
|
|
raiseOSError(osLastError())
|
|
let sockport = getSockName(sock.SocketHandle).int
|
|
k = 0
|
|
while k < messagesToSend:
|
|
zeroMem(addr(buffer[0]), 16384)
|
|
zeroMem(cast[pointer](addr(saddr)), sizeof(Sockaddr_in))
|
|
var message = "Message " & $(i * messagesToSend + k)
|
|
await sendTo(sock, addr message[0], len(message),
|
|
name, sizeof(Sockaddr_in).SockLen)
|
|
var size = await recvFromInto(sock, cast[pointer](addr buffer[0]),
|
|
16384, cast[ptr SockAddr](addr saddr),
|
|
addr slen)
|
|
size = 0
|
|
var grammString = $cast[cstring](addr buffer)
|
|
if grammString == message:
|
|
saveSendingPort(sockport)
|
|
inc(recvCount)
|
|
inc(k)
|
|
closeSocket(sock)
|
|
inc(i)
|
|
|
|
proc readMessages(server: AsyncFD) {.async.} =
|
|
var buffer: array[16384, char]
|
|
var slen = sizeof(Sockaddr_in).SockLen
|
|
var saddr = Sockaddr_in()
|
|
var maxResponses = (swarmSize * messagesToSend)
|
|
|
|
var i = 0
|
|
while i < maxResponses:
|
|
zeroMem(addr(buffer[0]), 16384)
|
|
zeroMem(cast[pointer](addr(saddr)), sizeof(Sockaddr_in))
|
|
var size = await recvFromInto(server, cast[cstring](addr buffer[0]),
|
|
16384, cast[ptr SockAddr](addr(saddr)),
|
|
addr(slen))
|
|
size = 0
|
|
var grammString = $cast[cstring](addr buffer)
|
|
if grammString.startsWith("Message ") and
|
|
saddr.sin_addr.s_addr == nativesockets.ntohl(INADDR_LOOPBACK.uint32):
|
|
await sendTo(server, addr grammString[0], len(grammString),
|
|
cast[ptr SockAddr](addr saddr), slen)
|
|
inc(msgCount)
|
|
saveReceivedPort(nativesockets.ntohs(saddr.sin_port).int)
|
|
inc(i)
|
|
|
|
proc createServer() {.async.} =
|
|
var name = prepareAddress(INADDR_LOOPBACK, serverPort)
|
|
var server = createAsyncNativeSocket(nativesockets.AF_INET,
|
|
nativesockets.SOCK_DGRAM,
|
|
Protocol.IPPROTO_UDP)
|
|
if bindAddr(server.SocketHandle, cast[ptr SockAddr](name),
|
|
sizeof(Sockaddr_in).Socklen) < 0'i32:
|
|
raiseOSError(osLastError())
|
|
asyncCheck readMessages(server)
|
|
|
|
var name = prepareAddress(INADDR_LOOPBACK, serverPort) # 127.0.0.1
|
|
asyncCheck createServer()
|
|
asyncCheck launchSwarm(cast[ptr SockAddr](name))
|
|
while true:
|
|
poll()
|
|
if recvCount == swarmSize * messagesToSend:
|
|
break
|
|
assert msgCount == swarmSize * messagesToSend
|
|
assert sendports == recvports
|
|
echo msgCount
|