<   2011年 08月 ( 29 )   > この月の画像一覧
(ネットワーク)TCPのスループットとRTTの関係
まず、RTT(往復遅延時間)というのはパケットを送信して受信した側が送信側にACKパケットを送り、送信側でそれを受取るまでの時間です。

e0091163_22465544.jpg


ネットワーク疎通テストに使う ping も結果に RTT が表示されますよね。(XP だと下記の time のところです)

>ping 10.0.120.1
Reply from 10.0.120.1: bytes=32 time=38ms TTL=54


さて、これとは別にTCPプロトコルにはウィンドウサイズというものがあります。
TCPは確実にパケットが届いたかどうかを確認するため、受信側が送信側にACKパケットを返すわけですが、毎回のパケット一つずつにACKを返すと非常に効率が悪いため、送信側が複数のパケットを送信し、その複数パケットに対してまとめて1回のACKを返すという仕組みをとってます。
この"複数のパケットの単位"がウィンドウサイズになるわけですね。

e0091163_22465868.jpg



(TCPウィンドウサイズはWindowsとかだとRWINと呼ばれており、一時期ブロードバンド回線ならこの値を大きくすることでネットの高速化につながるというような情報もちらほら見られました。)
このウィンドウサイズですが、基本的はOSで決まっています。
WindowsXPだと64KB(65535Byte)です。
WindowsXPやWindowsServer2003以前のウィンドウサイズについては、Windows Server 2003 SP1 での TCP 受信ウィンドウのデフォルト サイズ変更についてが参考になります。
TCPの当初の規格ではウィンドウサイズは最大64KBですが、後に規格拡張されたようで、次世代の TCP/IP スタックのパフォーマンスの拡張機能によるとVista以降だと最大16MBまで増やすようです。
(WindowsのウィンドウサイズはOSが徐々に大きくしてくれるようですね。つまり品質の悪い回線は小さく、いい回線は大きくしてくれるようです。最大値は上述の通りバージョンによって異なりますが。。)



さて、ここからが本題ですが、ウィンドウサイズとRTTからTCPのスループットを求めることができます。
TCPのACKはウィンドウサイズ毎に送信側に返ってくる(この時間がRTT)ので、TCPの理論最大スループットは下記の計算式で求めることができるわけです。
スループット(bps) = TCPウィンドウサイズ(KB) * 8 / RTT(S)

仮にウィンドウサイズ64KBで、RTTが10msだとすると、1秒間に64KBを100回送ることができるということになるので、下記のようになります。
65535byte * 8 / 0.010s = 52,428,000bps

これらの計算方法については下記サイトが参考になります。
教科書には載っていない ネットワークエンジニアの実践技術:第1回 FTPでスループット計測するときの注意事項|gihyo.jp
@IT:連載 基礎から学ぶWindowsネットワーク 第14回 信頼性のある通信を実現するTCPプロトコル(その1) 1.信頼性のある通信を実現するための仕組み(※2の部分に式があります)
速度向上の裏技 - ブロードバンドスピードテスト
ネットワ-クの速度を調べる方法


ということで、実際にテストをしてみました。
まず、RTTですが、Pingで計ってみます。

>ping -l 65500 192.168.0.11

Pinging 192.168.0.11 with 65500 bytes of data:

Reply from 192.168.0.11: bytes=65500 time=11ms TTL=128
Reply from 192.168.0.11: bytes=65500 time=11ms TTL=128
Reply from 192.168.0.11: bytes=65500 time=11ms TTL=128
Reply from 192.168.0.11: bytes=65500 time=11ms TTL=128

Ping statistics for 192.168.125.11:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 11ms, Maximum = 11ms, Average = 11ms

RTTは11ms=0.011sとなってますね。OSはXPなので、pingのパケット長はXPのウィンドウ最大サイズと同じ64KBにしています。
後は、計算式に当てはめてみると下記のようになります。
65500byte * 8 / 0.011s = 47,636,363bps

ん? 47Mbps???? 測定したのはL2スイッチを2個経由しただけの100Base-TX LANなので、こんなに遅いことはないはずです。

実際に、Iperfで下記の設定で測定してみたところ、94Mbpsはでる結果になりました。上記で求めた理論値(47Mbps)の倍になっています。

bin/iperf.exe -c 192.168.0.11 -P 1 -i 1 -p 5001 -w 64.0K -f b -t 10
...
[1904] 0.0-10.0 sec 118194176 Bytes 94547474 bits/sec



ここで引っ掛かったのは ping で計測した RTT の値です。
よくよく調べたら、Ping の応答に当たるICMPエコーは、送信元が送ったデータパケットをそっくりそのまま消すようです。(先頭のタイプフィールドにエコー応答(0)とするようですが。。)
つまり、Pingで64KBのパケットを送った場合、RTTの値は64KBの往復値つまり128KBの時間となるわけですね。
このPingの仕様に関しては、@IT:連載 基礎から学ぶWindowsネットワーク 第12回 TCP/IPプロトコルを支えるICMPメッセージ 1.ICMPメッセージ(1)pingでネットワークの速度を調査する - @ITが参考になります。


ということで、Pingで求めたRTTから論理スループットを計算するには下記のようにしないといけないようです。
スループット(bps) = 65,500byte * 2(往復するから) * 8 / RTT(S)

この式で上記の値を計算すると下記のようになり、実測とほぼ近い値が出ます。
65500byte * 2 * 8 / 0.011s = 95,272,727bps


Pingは最大65500バイトまでしか送れないので、それを超えたバイトをおくって純粋なRTT(ウィンドウサイズ先頭の送信開始から、ACKパケットが返ってくる時間)を測定できるようなフリーのツールがあればいいのですが、なかなかみあたりません。。。

もし、pingで65,535byteを送信できれば以下の式でスループットを計算できます。(XPの場合。他のOSの場合はそのOSのTCP最大ウィンドウサイズで測定する必要あり)
スループット(bps) = 65,535byte * 2(往復するから) * 8 / RTT(S)


しばらくの間にすっかりネットワークの詳しい動作について忘れてしまっている3流PGです。



参考:
@IT:連載 基礎から学ぶWindowsネットワーク 第15回 信頼性のある通信を実現するTCPプロトコル(2) 1.TCPパケットの構造
TCPの理論スループット: ネットワーク技術の覚書 - Kaztan's Cafe
@IT:ネットワークの設定は正しいか?
@IT:連載 基礎から学ぶWindowsネットワーク 第14回 信頼性のある通信を実現するTCPプロトコル(その1) 2.シーケンス番号とウィンドウ制御
第2回 TCP/IP高速化:大量データをまとめて送信 - スループット向上の切り札「TCP/IP高速化技術」:ITpro
ASCII.jp:WANの遅延を抑えて、レスポンスアップする
速度測定サイトについて|サービス情報サイト|サポート情報|ご利用中のお客さま|NTT東日本フレッツ公式 ウィンドウサイズとRTTによるスループットの関係図が参考になります。
ピカラ光サービス [徳島 香川 愛媛 高知] | (ピカラ光ねっと) ウィンドウサイズとRTTによるスループットの関係図が参考になります。
[PR]
by Jehoshaphat | 2011-08-29 22:48 | ネットワーク | Trackback | Comments(5)
(ネットワーク)回線速度測定ツールNetPerfを使ってみた

(ネットワーク)回線速度測定ツールJperfを使ってみた ではIperfをラッピングしたGUIベースのJperfを紹介しました。
しかし、JperfでUDPで測定すると、「WARNING: did not receive ack of last datagram after 10 tries.」 とか 「read failed: Connection reset by peer」と表示され、うまく測定できません。(バージョンは2.0.2です。)
また、UDPは測定時に帯域幅(UDP Bandwidth)を指定するのも意味が分かりませんし、どれくらいパケットロスしたのかも分かりません。

ということで、さらにネットワークベンチマークソフトを探してみたところ、NetPerfというのを見つけました。
ダウンロードはftp://ftp.cup.hp.com/dist/networking/benchmarks/netperf/からできます。(メインはLinux向けのようですが、ちゃんとWindows用のバイナリも有ります)

使い方ですが、サーバ側となる方は、下記のようにサーバ用のexeを起動しておくだけでOKです。(デフォルトだとポート12865が使われます)

>netserver-2.1pl1.exe
Starting netserver at port 12865


TCPのスループットを計測する場合は、クライアントで下記のようにします。

>netperf-2.1pl1.exe -H 192.168.0.10

結果は下記のようになります。

TCP STREAM TEST to 192.168.0.10
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

8192 8192 8192 10.00 20.57

RecvSocketSizebytesというのが受信側のソケットバッファでしょうか。デフォルトは8KBのようです。
SendSocketSizebytesというのが送信側のソケットバッファでしょうか。デフォルトは8KBのようです。
SendMessagebytesが送信パケットサイズでしょうね。これもデフォルトは8KBのようです。
ElapsedTimesecsが測定秒数のようです。デフォルト10秒です。
結果が、Throughput 10^6bits/sec ですね。Mbpsで表現されるようです。今回だと、93Mbpsという結果になりました。

オプションは下記のようになっています。

Usage: netperf [global options] -- [test options]

Global options:
-a send,recv Set the local send,recv buffer alignment
-A send,recv Set the remote send,recv buffer alignment
-c [cpu_rate] Report local CPU usage
-C [cpu_rate] Report remote CPU usage
-d Increase debugging output
-f G|M|K|g|m|k Set the output units
-F fill_file Pre-fill buffers with data from fill_file
-h Display this text
-H name|ip Specify the target machine
-i max,min Specify the max and min number of iterations (15,1)
-I lvl[,intvl] Specify confidence level (95 or 99) (99)
and confidence interval in percentage (10)
-l testlen Specify test duration (>0 secs) (<0 bytes|trans)
-o send,recv Set the local send,recv buffer offsets
-O send,recv Set the remote send,recv buffer offset
-n numcpu Set the number of processors for CPU util
-p port Specify netserver port number
-P 0|1 Don't/Do display test headers
-t testname Specify test to perform
-v verbosity Specify the verbosity level
-W send,recv Set the number of send,recv buffers

グローバルオプションを指定し、テストオプションを指定するという感じですね。
テストオプションで、メッセージ長やソケットサイズが指定できます。

テストオプションは下記のような感じです。

TCP/UDP BSD Sockets Test Options:
-D [L][,R] Set TCP_NODELAY locally and/or remotely (TCP_*)
-h Display this text
-m bytes Set the send size (TCP_STREAM, UDP_STREAM)
-M bytes Set the recv size (TCP_STREAM, UDP_STREAM)
-p min[,max] Set the min/max port numbers for TCP_CRR, TCP_TRR
-r bytes Set request size (TCP_RR, UDP_RR)
-R bytes Set response size (TCP_RR, UDP_RR)
-s send[,recv] Set local socket send/recv buffer sizes
-S send[,recv] Set remote socket send/recv buffer sizes


例えば送信ソケットサイズ64KB,メッセージサイズ64KBとするには下記のようにします。

netperf-2.1pl1.exe -H 192.168.0.10 -- -m 64512 -s 64512
TCP STREAM TEST to 192.168.0.10
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

8192 64512 64512 10.00 93.00




UDPで測定するときは下記のようにします。

>netperf-2.1pl1.exe -H 192.168.0.10 -t UDP_STREAM -- -m 1024

結果は下記のようになります。

UDP UNIDIRECTIONAL SEND TEST to 192.168.0.10
Socket Message Elapsed Messages
Size Size Time Okay Errors Throughput
bytes bytes secs # # 10^6bits/sec

64512 1024 10.00 111620 0 91.44
8192 10.00 85967 70.42

上段が送信、下段が受信側の結果のようです。
Messages Okay というのはどれくらいのメッセージを送信したかの数のようです。
送信時は 91Mbps も送信してるのに、受信時は 70Mbps になってますね。これはUDPのパケットが途中でロスしたからだと思われます。
ということで、実の実行スループットは下段の Throughput 10^6bits/sec になるようです。
LAN内だとあまりパケットロスしないですが、上記のテストのようにWAN(VPN)だとかなりUDPはパケットロスするのが分かります。


より詳しい使い方やオプションは下記参考サイトが役立ちます。
Netperf - TECHNERD::INIT:
Netperf でLANをチェック:
P2P@i 開発メモ: netperfを使った測定
netperfでネットワークパフォーマンスを測定
netperf の使い方 - takatan blog
[PR]
by jehoshaphat | 2011-08-26 12:11 | ネットワーク | Trackback | Comments(0)
(ツール)複数のユーザのIE履歴を確認したい
ターミナルサーバで数百人で利用してるんですが、それらの利用者のIEの履歴を調べる必要が出てきました。

で、見つけたのが MANDIANT Web Historian というツールです。
ダウンロードはhttp://www.mandiant.com/products/free_software/web_historian/からできます。

とりあえず、インストーラ形式なのでクライアントPCにインストールしました。
で、ドメイン管理者で起動し、メニューバー File→Scan で、Profile folder にターミナルサーバの管理共有経由で、ユーザプロファイルが入っているフォルダ(\\sv\c$\Documents and Settings 等)を指定し、解析を開始します。
ちょっと時間はかかりましたが、無事解析できました。
結果をエクスポートできるので、エクスポートしたデータを表計算ソフト等で解析すれば楽です。(かなりのデータになるとWeb Historianで何かしようとすると固まったりレスポンスが悪くなったりするので、エクスポートした方が無難でした)


詳しい使い方は、「Web Historian」を試してみる ー ツール:フォレンジック | Rubusigが参考になります。

IEだけでなくいろいろなブラウザに対応してたり、Cookieやダウンロードデータもとれるのもうれしいですね。
[PR]
by jehoshaphat | 2011-08-26 12:08 | ツール | Trackback | Comments(0)
(Linux)LogwatchのログメールをGmailに送りたい
Redhat系Linux CentOS には Logwatch というログ監視ツールが入っており、毎日の結果をCentOS内部の root ユーザにメールの形で送っています。

しかし、いちいちLinuxサーバにログインしてrootのメール見るは鬱陶しいということで、このroot宛てのサーバ内部からのメールをGmailに転送しようというのが今回の要件です。

送信元MTAにはデフォルトの sendmail を使うので、sendmail の設定が必要となります。この設定方法は sendmailからGmailへメールを転送する方法 : カブに乗ったプログラマSendmailでGmailに転送 - みゃあの主記憶装置 が参考なりました。
以下ほぼコピペですが、一応メモしておきます。

GmailはSMTPにSubmission(ポート587)で、SMTP認証とTLSを使っているので設定が結構厄介です。


1.sendmail.mcでの設定
まず、sendmail.mc で、SMTP/SubmissionやSMTP Auth の設定をします。

# vi /etc/mail/sendmail.mc

===dnl define(`SMART_HOST’, `smtp.your.provider’)dnl の次行に下記入力===
define(`SMART_HOST', `smtp.gmail.com')dnl
define(`ESMTP_MAILER_ARGS', `TCP $h 587')
define(`RELAY_MAILER_ARGS', `TCP $h 587')
FEATURE(authinfo, DATABASE_MAP_TYPE` -o 'MAIL_SETTINGS_DIR`authinfo')
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')
TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')

===dnl # DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA’)dnlのコメント解除===
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

===dnl DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea’)dnlのコメントを解除===
DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea')dnl

===dnl FEATURE(masquerade_envelope)dnlの次の行に以下の内容を入力===
FEATURE(masquerade_envelope)dnl
FEATURE(genericstable, DATABASE_MAP_TYPE` -o 'MAIL_SETTINGS_DIR`genericstable')
GENERICS_DOMAIN_FILE(MAIL_SETTINGS_DIR`genericsdomain')
FEATURE(`generics_entire_domain')

sendmail.mcの設定が終わったら、sendmail.cfを作成します。

m4 /usr/share/sendmail-cf/m4/cf.m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf


2.authinfo,genericstableの作成
SMTPの認証情報を格納するauthinfoファイルを作成します。

# vi /etc/mail/authinfo

AuthInfo:smtp.gmail.com "U:hoge" "I:hoge@gmail.com" "P:passwd"
(UはGmailの@より前、IはGmailのアドレス、Pはパスワードを入れます)

authinfoファイルが作成できたらauthinfo.dbファイルを作成します。makemapコマンドでsendmail用のデータベースマップを作成できるわけですが、hash オプションにより生パスワードが見られるリスクは軽減できますね。設定が終わったら、/etc/mail/authinfo は削除した方が安全かもしれません。

makemap hash /etc/mail/authinfo.db < /etc/mail/authinfo

また、下記コマンドでgenericsdomainファイルを作成します。

echo localhost >> /etc/mail/genericsdomain
echo `hostname`>> /etc/mail/genericsdomain

さらに、下記コマンドを実行しgenericstableファイルを作成します。

echo root nasubi@gmail.com > /etc/mail/genericstable
makemap hash /etc/mail/genericstable.db < /etc/mail/genericstable


これでsendmail再起動します。

/etc/rc.d/init.d/sendmail reload



3.root宛のメール転送設定
下記コマンドでaliasesファイルを編集しroot宛てのメールをGmailに送るようにします。

# vi /etc/aliases

(最下行の root: を修正(デフォルトはコメント))
# Person who should get root's mail
#root: marc
root: hoge@gmail.com

(保存してからnewaliasesで反映します)
# newaliases


下記コマンドでテストメールを送信できます。Gmail側で受信しているか確認してみましょう。

echo test|mail root


しかし、実際テストしてみると届きません。
/var/log/maillog でメールのログを見てみると下記のようになっていました。

Mar 10 10:49:40 localhost sendmail[21224]: p2A1md2K021223: to=hoge@gmail.com, ctladdr= (0/0), delay=00:01:01, xdelay=00:01:01, mailer=relay, pri=30559, relay=smtp.gmail.com [74.125.53.109], dsn=4.0.0, stat=Deferred: Connection timed out with smtp.gmail.com

タイムアウトしてるようです。
結局原因はファイアウォールの設定を見逃してたことでした。


ここで書いてるiptablesのスクリプトに下記を追加し、反映することでようやく無事にroot宛てメールが転送されるようになりました。

#################
#smtp(gmail) myhost-> any
#################
iptables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -s $myhost -d $any --dport 587 -j ACCEPT
iptables -A INPUT -p tcp -s $any --sport 587 -d $myhost -j ACCEPT
iptables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -s $myhost -d $any --dport 8001 -j ACCEPT
iptables -A INPUT -p tcp -s $any --sport 8001 -d $myhost -j ACCEPT



補足:
SMTP認証はせず、サブミッションポート(ポート587)対応だけなら、「1.sendmail.mcでの設定」で以下の部分のみ設定すればいいようです。


# vi /etc/mail/sendmail.mc

===dnl define(`SMART_HOST’, `smtp.your.provider’)dnl の次行に下記入力===
define(`SMART_HOST', `smtp.gmail.com')dnl
define(`ESMTP_MAILER_ARGS', `TCP $h 587')
define(`RELAY_MAILER_ARGS', `TCP $h 587')

===dnl # DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA’)dnlのコメント解除===
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

===dnl DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea’)dnlのコメントを解除===
DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea')dnl


あとは、sendmail.cfを作成し、sendmailサービスを再起動するだけです。

補足2:

sendmail.mcからsendmail.cf作成時に以下のようなメッセージが出た場合、sendmail-cf がインストールされていない可能性があるので、RedHat系の場合、yumでインストールしてやります。

# m4 /usr/share/sendmail-cf/m4/cf.m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
m4: /usr/share/sendmail-cf/m4/cf.m4: No such file or directory
/etc/mail/sendmail.mc:10: m4: cannot open `/usr/share/sendmail-cf/m4/cf.m4': No such file or directory

 ↓ sendmail-cfをインストール

#yum search sendmail-cf

[PR]
by jehoshaphat | 2011-08-25 12:20 | Linux | Trackback | Comments(0)
(HTML)IE8でページ内リンクが動かない
IE8でページ内リンクが動かない現象が発生してます。必ず起こるというわけではないんですが、ページの下の方へ行くほどこの現象が頻発してきます。

ページの構成としては a.php から b.php のtestというアンカーリンク(ページ内リンク)を呼び出す処理で、a.phpのリンク先には b.php#test としています。

原因ですが、b.php はDBの結果を表示するものでサーバの負荷が高く1ページのデータ量がかなり多いもの(テキストオンリーなのに1MB超え)となってます。
つまり、リクエストを投げてからページを表示するまで若干時間がかかってるようです。(Firebugで計測すると1.92sもかかってます)

おそらく、アンカーリンク先のページをまだ完全に読み込んでないのにIEがアンカーリンクへ飛ぼうとして、このような現象が起きたんだと思います。

対策としては本来は根本原因である1ページのデータ量を減らすべきなんでしょうが、とりあえずページを完全に読み込んだ段階で、Javascriptを使ってアンカータグへ飛ばすことにしました。

onLoad イベントがページの読み込みが完了したら動くのでここに処理書いてたんですが、それでも読み込みの方が遅延することがあったので、setTimeout を使ってアンカータグへ飛ぶのを意図的に(1秒)遅くすることにしました。

こんな感じです。


<html>
<head>
<script type="text/javascript" language="javascript">
<!--
function Href(){
if ( location.hash.length > 0){
//アンカータグを取得し、そこに飛ぶ
location.href = location.hash;
}
}
// -->
</script>
</head>
<body onLoad="setTimeout('Href()', 1000)">
<!-- DBから取得したコンテンツだが省略 -->
<a name="testname">ページの最後の方にあるアンカータグ</a>
</body>
</html>



参考:
ホームページ読み込み時の処理(onLoad) - イベント処理 - JavaScript入門
[JavaScript] URLのアンカーを取得する。 - うなの日記
JavaScript setTimeout:
setIntervalとsetTimeoutを調べた結果余分なことになった - 三等兵
[PR]
by jehoshaphat | 2011-08-25 12:18 | Webがらみ | Trackback | Comments(0)
(.Net)改行無しの全銀フォーマットを可読化する

全銀ファイルフォーマットを扱うことになったんですが、銀行側からくる口座振替のファイルをみて驚きました。
各レコードを区別する改行が無いのです。
全銀フォーマットが固定長なのは知ってましたが、改行が無いのは見づらいです。

ということで改行無の全銀フォーマットを見やすくするアプリを作りました。

取り合えず下記の要件を実装します。
・120桁おきに改行コードを入れてテキストに出力
・口座振替のフォーマットに従って各フィールドをカンマ区切りにしCSV出力
テキストボックス txtTargetFile.Text に読み込むファイルパスが格納されており、ラジオボタン rdoToCSV がチェック有りなら上記要件の2つ目CSV出力とします。

ソースはこんな感じです。ざっと作ったのできれいじゃないところも有りますが。(C#)

private void btnOK_Click(object sender, EventArgs e){
//1行の長さ
int cLineLength = 120;
//ファイル読み込み
string strFile = File.ReadAllText(txtTargetFile.Text, Encoding.GetEncoding("Shift_JIS"));
bool bHeadItemOut = false;
bool bDataItemOut = false;
bool bTrailerItemOut = false;
int idx = 0;
//変換後の結果格納
StringBuilder strOutput = new StringBuilder();
while (idx < strFile.Length){
//120文字読み込み
string strLine = strFile.Substring(idx, cLineLength);
//CSVにしたいなら
if (rdoToCSV.Checked){
int lIdx = 0;
int[] fWidth = new int[] { };
int iDataType = 0;
if (int.TryParse(strLine.Substring(0, 1), out iDataType)){
switch (iDataType){
case 1:
//ヘッダレコード
if (!bHeadItemOut){
strOutput.AppendLine("データ区分,種別コード,コード区分,依頼人コード,依頼人名,引落日,取引金融機関番号,取引金融機関名,取引支店番号,取引支店名,預金種目(委託者),口座番号(委託者),ダミー");
bHeadItemOut = true;
}
fWidth = new int[] { 1, 2, 1, 10, 40, 4, 4, 15, 3, 15, 1, 7, 17 };
break;
case 2:
//データレコード
if (!bDataItemOut){
strOutput.AppendLine("データ区分,引落金融機関番号,引落金融機関名,引落支店番号,引落支店名,ダミー,預金種目,口座番号,預金者名,振替金額,新規コード,顧客番号,振替結果コード,ダミー");
bDataItemOut = true;
}
fWidth = new int[] { 1, 4, 15, 3, 15, 4, 1, 7, 30, 10, 1, 20, 1, 8 };
break;
case 8:
//トレーラレコード
if (!bTrailerItemOut){
strOutput.AppendLine("データ区分,合計件数,合計金額,振替済件数,振替済金額,振替不能件数,振替不能金額,ダミー,預金者名,振替金額,新規コード,顧客番号,振替結果コード,ダミー");
bDataItemOut = true;
}
fWidth = new int[] { 1, 6, 12, 6, 12, 6, 12, 65 };
break;
case 9:
//エンドレコード
fWidth = new int[] { 1, 119 };
break;
default:
break;
}
foreach (int width in fWidth){
strLine = strLine.Insert(lIdx + width, ",");
lIdx = ++lIdx + width;
}
}else{
idx += cLineLength;
continue;
}
}
strOutput.AppendLine(strLine);
idx += cLineLength;
}
//保存
SaveFileDialog dlg = new SaveFileDialog();
dlg.InitialDirectory = Path.GetDirectoryName(txtTargetFile.Text);
dlg.FileName = Path.GetFileNameWithoutExtension(txtTargetFile.Text) + "_可読化";
dlg.Filter = "textファイル(*.txt)|*.txt|csvファイル(*.csv)|*.csv|すべてのファイル(*.*)|*.*";
if (rdoToCSV.Checked)
dlg.FilterIndex = 2;
if (dlg.ShowDialog() == DialogResult.OK){
File.WriteAllText(dlg.FileName, strOutput.ToString(), Encoding.GetEncoding("Shift_JIS"));
}
}

[PR]
by jehoshaphat | 2011-08-25 12:11 | .Net開発 | Trackback | Comments(2)
(.Net)SaveFileDialogで保存したファイルに拡張子がつかない
ファイルの保存ダイアログを SaveFileDialog で実装しようとしてました。

SaveFileDialog の AddExtension プロパティを true にすると現在のフィルタで選んでいる拡張子が自動的に付きます。
(デフォルトでAddExtensionはtrueです)

しかし、なぜか拡張子が付きません。。。

原因は、ファイル保存ダイアログを表示する前に SaveFileDialog.FileName でファイル名を指定してたんですが、それに "." があったためでした。

下記のような感じだったわけです。(C#)


SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = "2011.3.1";
dlg.Filter = "textファイル(*.txt)|*.txt|csvファイル(*.csv)|*.csv|すべてのファイル(*.*)|*.*";
dlg.AddExtension = true;
//ダイアログを表示する
if (dlg.ShowDialog() == DialogResult.OK)
{
MessageBox.Show(dlg.FileName);
}

どうやら FileName に "."(ドット/ピリオド) にあると拡張子が既にあると判断されて、つけてくれないようですね。
厄介な仕様です。
[PR]
by jehoshaphat | 2011-08-18 12:22 | .Net開発 | Trackback | Comments(0)
(オンラインツール)どのキーが押されたか判定する
今、キーボードのどのキーを押下しているかが分かるオンラインツールがMicrosoftにありました。
http://www.microsoft.com/appliedsciences/KeyboardGhostingDemo.mspx です。


Javascriptで実装してるようで、完全にブラウザだけで動きます。

まれにキーボードが暴走して特定のキーが通電しっぱなしってことがあるので、その確認に使えそうです。

ただ、英語版キーボードを対象としてるので、日本語独特のキーが認識できないのは残念です。

参考:
キーボードの同時押し検出ソフト - forPCActionGamer Wiki
[PR]
by jehoshaphat | 2011-08-18 12:15 | ツール | Trackback | Comments(0)
PCから高周波の異音がする原因は?

ノートPCからキーンという高周波がするという問い合わせがありました。

で預ってみたところたしかに聴力検査で聞くような高周波の音がします。

異音は液晶が点灯している時しか鳴らず、軽度を低くすると今度はジーというような低周波のノイズ音になります。

以前にも友人が似たような現象があったので大体目星は付いていました。
原因はやはり液晶ディスプレイのバックライトに(蛍光管)に使われているインバータ不良でした。

俗に言う「インバータ鳴き」現象です。

最近はバックライトにLEDを使うのも出てきていますが、あれに置き換わればインバータが無いのでこういう現象は発生しなくなるんでしょうね。。
[PR]
by jehoshaphat | 2011-08-18 12:10 | ハードウェア | Trackback | Comments(0)
PowerPoint Viewer 2007が起動しない

XPのPCに PowerPoint Viewer 2007 をダウンロードしてインストールしたんですが、起動しません。

ググるとかなり引っ掛かるので、どうやら有名な現象のようです。

対処法としては、下記の通りにすればいいようです。
1.
%ProgramFiles%\Microsoft Office\Office12\ に "1033" というフォルダを作る。

2.
%ProgramFiles%\Microsoft Office\Office12\1041\PPVWINTL.DLL をコピーして、%ProgramFiles%\Microsoft Office\Office12\1033 フォルダ内に貼り付け。


参考:
MSサポート:PowerPoint Viewer 2007 を起動しようとしても実行されない
PowerPoint Viewer 2007 が起動しない
自作PC使ってます PowerPoint Viewer 2007 が起動しない
[PR]
by jehoshaphat | 2011-08-18 12:09 | 豆知識 | Trackback | Comments(0)