Vistaの電源管理
XPならタスクマネージャからシャットダウンできたが、
Vistaはできないので調べてみた。
マザーボードのBIOSの設定はS3にしてある。
S3でないとスリープの時にファンが落ちないため。
REM 終了、電源を切る、シャットダウン
shutdown.exe -s -t 0REM 再起動、リブート
shutdown.exe -r -f -t 0
ここまでは問題ないが、問題はスリープだ。
スリープとはデスクトップPCの場合、
メモリとディスク両方に保存され、通常はメモリから復帰するが、
電源障害などでメモリから消えた場合はディスクから復帰するというものだ。
という例があったが、これらを実行し電源を入れると、
rundll32.exe PowrProf.dll,SetSuspendState Sleeprundll32.exe PowrProf.dll,SetSuspendState 0,1,0
BIOSから立ち上がり、ディスクから復帰しているようだ。
これではハイバネート(休止状態)だ。
仕方なくプログラムを組むことにした。
PowerState.Suspendとあるが、実際の挙動はスリープそのものだ。
// .NETのコードだが、WinAPIのSetSuspendStateを呼び出しているだけ。
// WinAPIの場合の第1引数はFALSE。
Application.SetSuspendState(PowerState.Suspend, false, false);
コンセントを抜いて放置してから立ち上げると、ディスクから復帰してくれる。
ただし、問題もある。
Vistaのメニューからスリープにした場合もそうだが、WOLが上手くいかない場合がある。
シャットダウン | 成功 |
ハイバネート | 成功 |
スリープでメモリから | 成功 |
スリープでディスクから | 失敗 |
これは設定の問題なのか、Vistaの問題なのか特定が難しいので保留。
外出先からのWOL(Wake On LAN)
随分前から使用しているけど、一応書いておく。
デバイスマネージャのネットワークアダプタの詳細設定から
Shutdown Wake-On-LanをEnabledにしておく。
自宅サーバーがIISで.NETが使えるなので、
以下のソースでマジカルパケットを投げるだけ。
byte[] buf = new byte[102];
int p = 0;
for (int i = 0; i < 6; i++) {
buf[p++] = 0xFF;
}for (int i = 0; i < 16; i++) {
// 物理アドレスを指定
buf[p++] = 0xXX;
buf[p++] = 0xXX;
buf[p++] = 0xXX;
buf[p++] = 0xXX;
buf[p++] = 0xXX;
buf[p++] = 0xXX;
}
using (UdpClient udp=new UdpClient()) {
udp.Connect(IPAddress.Broadcast, 2304);
udp.Send(buf, 102);
}
WindowsでのOpenVPN(1)
環境を再構築していて、以前のメモでは分かりづらかったので修正する。
公開鍵方式は面倒なので静的鍵方式を用いる。
1対1しかできないが、今回の目的には十分だと思う。
詳しくは静的鍵Mini-HOWTOを参照。
以下の環境下で接続したい。
ルーター | 192.168.11.1 | ||
デスクトップ | サーバー | Windows XP SP2 | 192.168.11.2 |
ノート | クライアント | Windows XP SP2 | 192.168.11.3 |
インストール
openvpn-2.0.9-install.exeをサーバー、クライアントにインストールする。
鍵を生成する
サーバーのプログラムメニューから
"Generate a static OpenVPN key"を実行すると、
configフォルダに"key.txt"が生成される。
これをクライアントのconfigフォルダにもコピーしておく。
設定ファイルを作成する
以下の内容で"server.ovpn"と"client.ovpn"というテキストを作成し、
それぞれのconfigフォルダに入れておく。
server.ovpn
dev tun
ifconfig 10.8.0.1 10.8.0.2
secret key.txt
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
client.ovpn
remote 192.168.11.2
dev tun
ifconfig 10.8.0.2 10.8.0.1
secret key.txt
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
OpenVPNが作成した"ローカルエリア接続(n)"のIPを設定する
サーバー | 10.8.0.1 | 255.255.255.0 |
クライアント | 10.8.0.2 | 255.255.255.0 |
System.NetとWinInet
5つのスレッドを用いて50ページをダウンロードした場合の
パフォーマンスを比較してみた。
平均すると、
WinINet 4.140秒
Sysetm.Net 6.109秒
Sysetm.Netを非同期で試しても結果が変わらない。
ずいぶん遅いと思い調べていたら、
ServicePointManager.DefaultConnectionLimitがデフォルト2なので、
これを変更する必要があるらしい。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndotnet/htm/frame_1.asp
結果 4.512秒
public static string DownloadString(IntPtr inet, string uri, Encoding enc) {
IntPtr req = InternetOpenUrl(
inet, uri, "", -1, /*INTERNET_FLAG_RELOAD*/0x80000000, IntPtr.Zero);
byte[] bytes = new byte[4096];
string html = string.Empty;
using (MemoryStream ms=new MemoryStream()) {
for (;;) {
uint len = 0;
if (!InternetReadFile(req, bytes, 4096, ref len)) break;
if (len == 0) break;
ms.Write(bytes, 0, (int)len);
}
ms.Position = 0;
using (StreamReader sr=new StreamReader(ms, enc)) {
html = sr.ReadToEnd();
}
}
InternetCloseHandle(req);
return html;
}public static string DownloadString(string uri, Encoding enc) {
HttpWebRequest req = WebRequest.Create(address) as HttpWebRequest;
req.Encoding = enc;
HttpWebResponse res = req.GetResponse() as HttpWebResponse;
using (StreamReader sr=new StreamReader(res.GetResponseStream(), enc)) { return sr.ReadToEnd();
}
}