如何在Ruby中通过套接字复制文件?

huangapple go评论60阅读模式
英文:

How to copy a file over a socket in Ruby?

问题

以下是你提供的代码的中文翻译部分:

第一个示例:

我尝试通过套接字复制文件。这部分是有效的。但是,脚本从未结束。我一直陷入了一个无休止的while循环中,读取套接字上的数据。非常感谢您的提前帮助。

require 'socket'

server = TCPServer.new 5555

Thread.new do
  client = server.accept

  file = File.new('files.zip', 'rb')

  while line = file.read(1024)
    client.write line
  end
end

socket = TCPSocket.new('localhost', 5555)
file = File.new('files_backup.zip', 'wb')
while line = socket.read(1024)
  file.write line
end

第二个示例:

我也尝试了使用nil

require 'socket'

server = TCPServer.new 5555

Thread.new do
  client = server.accept
  client.write File.binread 'files.zip'
  client.write nil
end

socket = TCPSocket.new('localhost', 5555)
file = File.new('files_backup.zip', 'wb')

while line = socket.read(1024)
  unless line
    break
  end
  file.write line
end

file.close

第三个示例(更新后的,使用数据长度):

使用读取的长度进行了更新。

require 'socket'

server = TCPServer.new 5555

Thread.new do
  client = server.accept
  content = File.binread('hackers.zip')
  client.write content.length
  client.write content
end

socket = TCPSocket.new('localhost', 5555)
file = File.new('hackers_backup.zip', 'wb')

length = socket.gets.to_i
content = socket.read length
file.write content
file.close
英文:

I'm trying to copy a file over a socket. This works. However, the script never ends. I get stuck in an endless while loop reading data over the socket. Thank you so much in advance.


server = TCPServer.new 5555

Thread.new do
  client = server.accept

  file = File.new('files.zip', 'rb')

  while line = file.read(1024)
    client.write line
  end
end

socket = TCPSocket.new('localhost', 5555)
file = File.new('files_backup.zip', 'wb')
while line = socket.read(1024)
  file.write line
end

I tried with nil as well.

require 'socket'

server = TCPServer.new 5555

Thread.new do
  client = server.accept
  client.write File.binread 'files.zip'
  client.write nil
end

socket = TCPSocket.new('localhost', 5555)
file = File.new('files_backup.zip', 'wb')

while line = socket.read(1024)
  unless line
    break
  end
  file.write line
end

file.close

Updated with the length as the size of the read.

require 'socket'

server = TCPServer.new 5555

Thread.new do
  client = server.accept
  content = File.binread('hackers.zip')
  client.write content.length
  client.write content
end

socket = TCPSocket.new('localhost', 5555)
file = File.new('hackers_backup.zip', 'wb')

length = socket.gets.to_i
content = socket.read length
file.write content
file.close

答案1

得分: 0

您从未告诉脚本停止阅读。`read(1024)` 函数是阻塞的,在套接字打开的情况下它永远不会返回 nil。最简单的解决方法是在文件发送后关闭套接字。当您不再期望更多数据时,还应关闭文件以写入数据。

如果您想保持连接,必须使用某种协议。也许可以通过以文件长度开始通信,然后读取第一行,随后从套接字读取预期字节数。

奖励点是在标头中发送校验和,并在接收时验证文件。
英文:

You never tell the script to stop reading. The read(1024) function is blocking and it never returns nil while the socket is open. Easiest fix would be to close the socket when the file is sent. You should also close the file to write the data when you don't expect more.

require 'socket'
server = TCPServer.new 5555

Thread.new do
  client = server.accept
  file = File.new('files.zip', 'rb')
  while line = file.read(1024)
    client.write line
  end
  client.close
end

socket = TCPSocket.new('localhost', 5555)
file = File.new('files_backup.zip', 'wb')
while line = socket.read(1024)
  file.write line
end
file.close

If you want to keep the connection you have to come with some kind of a protocol. Maybe start a communication with a line saying the file length. Then you can read the first line and later read the expected number of bytes from the socket.

require 'socket'
server = TCPServer.new 5555

Thread.new do
  client = server.accept
  file = File.new('files.zip', 'rb')
  client.puts file.size
  while line = file.read(1024)
    client.write line
  end
end

socket = TCPSocket.new('localhost', 5555)
length = socket.gets.to_i
File.open('files_backup.zip', 'wb'){|f| f.write(socket.read(length)) }

Bonus point would be sending a checksum in the header and validating the file upon receive.

huangapple
  • 本文由 发表于 2023年3月8日 18:43:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75671990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定