http最高
先日Fedora Core 2 LinuxのDVDイメージをダウンロードしようとして,そのファイルサイズが32bitを越えていることに気付いた.
例えば以下はKDDI研究所のミラーサイトであるが,HTTPでこのファイルにアクセスしたときの挙動が面白い.
http://ftp.kddilabs.jp/Linux/packages/fedora/core/2/i386/iso/
ftp://ftp.kddilabs.jp/Linux/packages/fedora/core/2/i386/iso/
HTTP/1.1 301 Moved Permanently
Date: Wed, 26 May 2004 16:12:01 GMT
Server: Apache
Location: ftp://ftp.kddilabs.jp/Linux/packages/fedora/core/2/i386/iso/FC2-i386-DVD.iso
現状httpサーバ/クライアントともに(4GB)2GBを越えるファイルを扱えるものは意外と少ない.それを考えるとこのリダイレクトは妥当と言えるかもしれないが,Internet Explorer 6.0はFTPでもファイルサイズの下位32bitしか見ないようで結局ダウンロードに失敗する*1.世の中なかなかうまく行かないものだ.ちなみにFFFTPではダウンロードに成功している.
なお,HTTPによるダウンロードに関していくらか実験してみた結果が以下である.
- System.Net.WebClient (.NET Framework 1.1)
- "Content-Length"を下位32bitしか見ない.負値になったら即切断.
- Internet Explorer 6.0
- "Content-Length"の下位32bitしか見ない.負値になったら即切断.
- Irvine 1.1.1
- ダウンロードサイズが2GBを越えてから表示が負値になる.4GBを越えると表示が-1になる.ダウンロードが終わる(向こうから切断される)とダウンロードが失敗したと解釈される(そしてデフォルトでは再びダウンロードを開始する).
- Mozilla 1.8a1
- ダウンロードサイズが2GBを越えてから表示が負値になる.4GBを越えたあたりでダウンロードが停止する.
4GBを越えるデータを扱えるhttpdサーバだが,探すのが面倒なのでC#でごく簡単なものを作ってみた.以下,http的には無茶苦茶だがとりあえず山のような"!"を返すプログラムである.
>
using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Globalization;
using System.Text;static void Server()
{
IPAddress addr = IPAddress.Loopback;
System.Net.Sockets.TcpListener serv = new System.Net.Sockets.TcpListener( addr, 80 );
serv.Start();
while(true)
{
using( TcpClient client = serv.AcceptTcpClient() )
{
using( NetworkStream ns = client.GetStream() )
{
try
{
StreamReader sr = new StreamReader( ns );// 全体のサイズ
long dataSize = 0x110000000;// 一度に出力するデータのサイズ
int dataBlock = 4*1024*1024;while(true)
{
string line = sr.ReadLine();
if( line == "" )
{
break;
}
}DateTimeFormatInfo dtf = CultureInfo.InvariantCulture.DateTimeFormat;
string msg = string.Format(
"HTTP/1.1 200 OK\r\n" +
"Date: {0}\r\n" +
"Server: TestServer\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: {1}\r\n" +
"\r\n",
DateTime.Now.ToString(dtf.RFC1123Pattern, CultureInfo.InvariantCulture),
dataSize );byte[] data = Encoding.ASCII.GetBytes( new string('!',dataBlock) );
StreamWriter sw = new StreamWriter( ns );
sw.Write( msg );
sw.Flush();
for( long i = 0; i < dataSize / dataBlock; ++i )
{
ns.Write( data, 0, data.Length );
}
}
catch(Exception)
{
}
}
}
}
}
*1:最初の200MBちょっとしかダウンロードしない
Fortran最高
研究室での初仕事がとある古いSunのワークステーションで動いていたFortranプログラム*1をLinux上のg77に移植するというものだったのだが,実質1ヶ月ぐらいかかって本日ようやく完了.最初は実機が無くて苦労したが,実機が復旧してデバッグ環境が整ってからはからはさすがに捗った.
ちなみに最も時間を割かれた問題はFortranの"Direct Access File"の非互換性による計算結果の不一致であった.Fortranには固定長レコードのバイナリファイルを簡単に扱う機能がある.これがSunのワークステーションではビッグエンディアンで記録されていて,AT互換機上でのg77ではこれがリトルエンディアンで記録されていたというのが顛末だ.このプログラムで使用するほとんどのデータはFITS*2ファイルで提供されていたため逆に発覚が遅れてしまったかもしれない.ちなみに同じAT互換機上でもIntel Fortranの"Direct Access File"には色々ヘッダ情報が付いていて,エンディアンは同じでもg77と互換性がない.結局それぞれの環境でテキストダンプするプログラムを作り,テキスト経由でデータの変換を行っている.まあこれもある意味のマーシャリングだろうか.
今回移植したプログラムはF77と呼ばれる規格に基づいて書かれている.この規格は悪名高い暗黙の変数宣言を許しており,実際移植中にtypoらしきものをいくつか見つけてしまった.恐らくバグなのだろうが,直すと動かなくなりそうなのが恐い.
FortranでもF90やF95ではそれなりにモジュール化や生産性への配慮がなされている.これらの配慮を有効に利用してコーディングすればそれなりに読みやすいソースコードとなるはずだ.ただし私は経歴上F90やF95で書かれた大規模プロジェクトというのはあまり知らない.しかしそれでもパフォーマンス的な観点から今でもFortranを利用するという局面はあるようだ.
http://www-6.ibm.com/jp/developerworks/linux/030613/j_l-sc11.html
最後にGeant4というライブラリを紹介しておこう.これは核物理の分野で最近開発されたライブラリで,素粒子反応測定器のシミュレータである.
http://wwwasd.web.cern.ch/wwwasd/geant4/geant4.html
何故このライブラリを紹介するかというと,これがFortranからC++への移行という側面を持ったソフトウェアだからだ.これらの事情に関しては以下の資料がとても面白い.
http://geant4.kek.jp/~sasaki/OO99/
第一線で働く物理学者がC++でのカスタムメモリアロケータやデータのシリアライズで苦労している姿を想像すると,案外物理の世界も身近に感じられたりはしないだろうか?