From: AOKI Yoshihiro Date: 2011-07-22T11:05:43+09:00 Subject: [ruby-list:48235] TCPSocketで大きいファイルを送ると中断してしまう あおきと申します。 RubyでWebブラウザの真似をして, ネットワークプリンタに下のようなヘッダでPDFを送りつけているのですが, 確立された接続がホスト コンピュータのソウトウェアによって中止されました。 というエラーが出て,毎回60%強のところで中断してしまいます。 エラーになるPDFは172,410,964バイト(164MB)で, 別の85,379,347バイト(81MB)程度だとうまくいくので, ファイルサイズの関係かと思っています。 --------- POST /cgi-bin/uploadfile.exe HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* Referer: http://192.168.208.39/cgi-bin/uploadfile.exe?printoption Accept-Language: ja Content-Type: multipart/form-data; boundary="--616f6b69124a64727a2b104c" Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322) Host: 192.168.208.39 Content-Length: 172413947 Proxy-Connection: Keep-Alive Pragma: no-cache --------- RubyはVC2010でコンパイルした C:\ruby -v ruby 1.9.2p180 (2011-02-18 revision 30909) [i386-mswin32_100] を使っています。 SocketもHTTPプロトコルも初めてで, ・自分が悪いのか ・プリンタが悪いのか ・Winsockのせいなのか 判断しかねています。 下のBUFSIZEのサイズを変えてみたり(現状0x100000,以前0x1000), BUFSIZEを指定せず全量を送りつけたりしましたが変わらず。 BUFSIZEを省略した場合はテキストとして送信されるようですが, binmodeや "rb" で回避しているつもりです。 ヒントをいただけると幸いです。 スクリプトの抜粋: --------- begin sock = TCPSocket.open(@ip, 80) rescue raise PrintError.new("プリンタに接続できませんでした") end fsize = File.stat(@filename).size sock.binmode sock.syswrite header(opt.length+fsize+footer.length) r = sock.gets while (z = sock.gets); if z.chomp.empty? then break end end if r.chomp != RESPONSE_CONTINUE sock.close raise PrintError.new("ヘッダ送信時にプリンタがエラーを返しました") end begin sock.syswrite opt ps = open(@filename, "rb") pb = ProgressBar.new(fsize) while true i = sock.syswrite(ps.sysread(BUFSIZE)) pb.step(i) end rescue EOFError sock.syswrite(footer) pb.finish end --------- ---- 青木