レジューム可能なファイル交換スクリプト
一対一でファイルを送ってもらっていたんだけど、途中で接続が切れて中途半端なファイルができちゃったよママン、ってな状況で役立つかもしれないスクリプト。ただし、ファイルを送信する人が開放済みのポートを持っていて、すぐに連絡を取れるような条件でないと使えないと思われ。
うさげ
クライアント側に既にファイルが存在するときは途中からダウンロードを行い、存在しないときは普通にダウンロードを行う。クライアントは指定したファイルを受信すると終了するが、サーバは何度でも接続を受け付けることができる。サーバの終了は Ctrl+C でおk。
# クライアント側 ruby resume.rb [サーバのアドレス] [サーバのポート] [受信したいファイル名] # サーバ側 ruby resume.rb [待ち受けするポート]
ソース
#!/usr/local/bin/ruby require 'socket' case ARGV.size when 1 then $port = ARGV[0] when 3 then $addr, $port, $path = ARGV[0], ARGV[1], ARGV[2] else puts("<Usage>") puts("client: resume.rb server_addr server_port filename") puts("server: resume.rb listen_port") exit end def client(sock) puts("connected!") sock.puts($path) File.open($path, File::WRONLY | File::CREAT | File::BINARY) {|f| # ポインタ移動 f.seek(0, IO::SEEK_END) pos = f.tell.to_i sock.puts(pos) # レジューム puts("receiving #{$path} from #{pos}") while buf = sock.read(65536) do f.write(buf) end } puts("complete!") end def server(sock) puts("accepted!") $path = sock.gets.chop File.open($path, "rb") {|f| # ポインタ移動 pos = sock.gets.chop.to_i f.seek(pos, IO::SEEK_SET) # レジューム puts("sending #{$path} from #{pos}") while buf = f.read(65536) do sock.write(buf) end } puts("complete!") end if $addr then begin puts("starting client") sock = TCPSocket.open($addr, $port) client(sock) rescue puts($!) ensure sock.close if sock end else begin puts("starting server") s = TCPServer.open($port) while sock = s.accept do begin server(sock) rescue puts($!) ensure sock.close end end rescue puts($!) ensure s.close if s end end