英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论