Sockets 从光纤通过套接字发送和读取数据
试图找出如何通过套接字发送/读取数据。在远程服务器上,我创建了新的netcat-l 4444,并从本地发送文本数据回显测试| netcat remote.host 4444。这总是很好用的 试图复制:Sockets 从光纤通过套接字发送和读取数据,sockets,crystal-lang,fibers,Sockets,Crystal Lang,Fibers,试图找出如何通过套接字发送/读取数据。在远程服务器上,我创建了新的netcat-l 4444,并从本地发送文本数据回显测试| netcat remote.host 4444。这总是很好用的 试图复制: require "socket" HOST = "remote.host" PORT = 4444 ch_request = Channel(String).new ch_response = Channel(String).new spawn do socket = TCPSocket
require "socket"
HOST = "remote.host"
PORT = 4444
ch_request = Channel(String).new
ch_response = Channel(String).new
spawn do
socket = TCPSocket.new(HOST, PORT)
loop do
select
when request = ch_request.receive
socket << request
socket.flush
end
if response = socket.gets
ch_response.send response
end
end
end
sleep 0.1
ch_request.send "hello"
loop do
select
when response = ch_response.receive
pp response
end
end
在我的梦中,我将数据发送到通道,从第一个循环读取数据,然后发送到套接字。同样的方法,但从第二个循环读取它需要相反的顺序
在实践中,这种情况不会发生。在本地连接后,我得到了测试,无法发回任何东西。在远程,我可以发送到本地,但在本地,我只得到了一次空字符串,之后就什么也没有了
这种行为是什么意思?如何实现计划的?您没有显示这一点,但我想您还有第二个实现,它使用了netcat-l等效的TCPServer 您需要使用单独的光纤来读取/写入插槽和通道。在看不到服务器的情况下,很难判断到底发生了什么,但我认为最终会陷入死锁,双方都在等待另一方或用户的输入,但无法继续实际发送或读取任何内容。换句话说,您联锁了发送/接收部分,要求另一方小心地作出反应和相互作用,以免锁定客户端。这显然是一种脆弱的方法 相反,您应该确保任何光纤在一个环路中不会执行多个操作。一个从插槽接收数据并将其转发到通道,第二个从通道接收数据并将其转发到插槽,第三个从读卡器侧通道接收数据并打印或执行您想执行的任何操作,最后一个填充发送器通道。这样,任何操作都无法阻止其他操作之一。当然,这些光纤中的一个应该是主程序光纤 在服务器中,您还需要一根光纤来接受客户端连接,并为每个连接生成发送方和接收方循环
最后请注意,如果select语句具有单个分支,则当分支无效时,可以直接进行调用。如果您需要在同一光纤中同时读取或写入多个通道,则select非常有用,因此,例如,如果您有多个通道提供要发送到套接字的数据,则可以使用select使消息不会因两个光纤同时写入同一套接字而损坏。select的另一个用例是发送或接收带有超时的频道。正在寻找类似问题的答案。我想要的最终结果如下所示:
# Open socket for simulate remote server: `netcat -v -4 -l 4444`
require "socket"
HOST = "remote.host"
PORT = 4444
# JFYI: In real life this packed into class and I use class variable instead consts.
TUBE_REQUEST = Channel(String).new
TUBE_RESPONSE = Channel(String).new
SOCKET = TCPSocket.new(HOST, PORT)
spawn do
until SOCKET.closed?
if request = TUBE_REQUEST.receive
SOCKET << request
SOCKET.flush
end
end
end
spawn do
until SOCKET.closed?
if response = SOCKET.gets
TUBE_RESPONSE.send response
end
end
end
sleep 0.1
def receive_response
TUBE_RESPONSE.receive
end
def send(message, wait_for_response = true)
TUBE_REQUEST.send message
receive_response if wait_for_response
end
send("command with response")
send("command with new line and response\n")
send("command without new line and response", false)
它将发送每个命令并等待应答,但最后一个命令来自远程,然后调用下一个命令。>[…]第二次使用TCPServer实现。对于开发,我使用类似于上述的netcat。此命令用-l打开套接字,监听输入连接并打印数据。发送/读取数据不需要单独的服务器。对于像服务器这样的实现,我有Nsqd,它可以向我发送二进制流数据。您的回答非常有用,并扩展了我对光纤/通道的了解,我解决了这个问题。非常感谢您抽出时间!