gpt4 book ai didi

sockets - 运行脚本时,Julia 套接字 TCP 连接被拒绝,而不是 REPL

转载 作者:行者123 更新时间:2023-12-01 16:19:12 25 4
gpt4 key购买 nike

我正在遵循此处找到的简单 TCP 示例:https://docs.julialang.org/en/v1/manual/networking-and-streams/#A-simple-TCP-example-1 。代码如下(我对链接稍加修改):

using Sockets
using Printf

# listen will create a server waiting for incoming connections on the specified
# port (in this case it will be localhost::2000)
@async begin
server = listen(2000)
x :: Int = 1
while true
sock = accept(server)
@printf "Connection number %d\n" x
x += 1
end
end


for i = 1:10
connect(2000)
end

当我在 REPL 中执行命令时,它可以正常工作并生成以下输出:

julia> @async begin
server = listen(2000)
x :: Int = 1
while true
sock = accept(server)
@printf "Connection number %d\n" x
x += 1
end
end
Task (runnable) @0x00000001169d06d0

julia> for i = 1:10
connect(2000)
end
Connection number 1
Connection number 2
Connection number 3
Connection number 4
Connection number 5
Connection number 6
Connection number 7
Connection number 9
Connection number 10

但是,当我尝试将这些命令放入文件中时:

using Sockets
using Printf

# listen will create a server waiting for incoming connections on the specified
# port (in this case it will be localhost::2000)
@async begin
server = listen(2000)
x :: Int = 1
while true
sock = accept(server)
@printf "Connection number %d\n" x
x += 1
end
end


for i = 1:10
connect(2000)
end

并使用 julia <scriptName> 运行或(来自 REPL 内)include("<scriptName>")我收到以下错误消息:

ERROR: LoadError: IOError: connect: connection refused (ECONNREFUSED)
Stacktrace:
[1] wait_connected(::TCPSocket) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.3/Sockets/src/Sockets.jl:520
[2] connect at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.3/Sockets/src/Sockets.jl:555 [inlined]
[3] connect at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.3/Sockets/src/Sockets.jl:541 [inlined]
[4] connect at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.3/Sockets/src/Sockets.jl:537 [inlined]
[5] top-level scope at <pathToFile>:18
[6] include at ./boot.jl:328 [inlined]
[7] include_relative(::Module, ::String) at ./loading.jl:1105
[8] include(::Module, ::String) at ./Base.jl:31
[9] include(::String) at ./client.jl:424
[10] top-level scope at REPL[1]:1
in expression starting at <pathToFile>:17

我如何从脚本运行这个程序?我对 Julia 和套接字相当陌生,所以如果这是一个简单的问题,我深表歉意!!

最佳答案

您收到错误,因为如果 listen 尚未运行,connect 将失败。正如您所发现的,在服务器和客户端之间引入一个小暂停可以解决这个问题;让我们尝试更详细地解释这一点。

在基于 REPL 的交互式版本中,一旦使用 @async 创建服务器任务,控制权就会返回到 REPL,后者执行阻塞操作(例如等待新命令可以在命令行中输入)。这使调度程序有机会将控制权交给新创建的任务。对 listen 的调用出现在早期,确保每当控制再次到达客户端时 - 并执行对 connect 的调用 - 服务器正在监听。

在脚本版本中,服务器任务被创建并调度,但调度程序没有任何机会实际运行它,因为主任务在运行 connect 之前不会执行任何阻塞调用。因此,在执行连接时没有人在监听套接字,并且调用失败。但是,在此位置放置的任何阻塞调用都将为调度程序提供运行服务器任务的机会。这包括 sleep (如您所指出的,任意少量的时间),但也包括任何执行 I/O 的函数:一个简单的 println("hello") 就可以了也是。

我认为解决问题的更简洁的方法是确保首先执行对 listen 的调用,通过预先同步运行它:

using Sockets
using Printf

# listen will create a server waiting for incoming connections on the specified
# port (in this case it will be localhost::2000)
server = listen(2000)
@async begin
x = 1
while true
sock = accept(server)
@printf "Connection number %d\n" x
x += 1
end
end

for i = 1:10
connect(2000)
end


现在还剩下另一个问题:当客户端循环终止时,所有对 connect 的调用都已发出,但不一定所有对 accept 的相应调用都已发出是时候运行了。这意味着您可能会得到被截断的输出,例如:

Connection number 1
Connection number 2
Connection number 3
Connection number

您需要在任务之间进行进一步协调才能纠正此问题,但我怀疑第二个问题可能仅与此处发布的 MWE 有关,并且可能不会出现在您的实际用例中。

例如,服务器大概是要向客户端发送一些内容。在这种情况下,在套接字上执行的读写操作自然会同步这两个任务:

using Sockets
using Printf

# listen will create a server waiting for incoming connections on the specified
# port (in this case it will be localhost::2000)
server = listen(2000)
@async begin
x = 1
while true
sock = accept(server)
msg = "connection number $x\n"
print("Server sent: $msg")
write(sock, msg)
x += 1
end
end

for i = 1:10
sock = connect(2000)
msg = readline(sock)
println("Client received: $msg")
end

上面的示例正确地生成了完整的(未截断的)输出:

Server sent:     Connection number 1
Client received: Connection number 1
Server sent: Connection number 2
Client received: Connection number 2
...
Server sent: Connection number 10
Client received: Connection number 10

关于sockets - 运行脚本时,Julia 套接字 TCP 连接被拒绝,而不是 REPL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60326237/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com