プログラミングとか日常とかの覚書っぽいなにか
× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
ネットワーク通信を使用するプログラムなどでは、設定ファイルやユーザー入力でテキスト形式(ドット区切り)のIPv4アドレス(例えば「192.168.1.15」など)を使用することが多いです。この場合、プログラムでは、文字列が有効なIPv4アドレス形式であるかどうかを判定し、さらには4バイト整数形式のアドレスに変換しなければならないと思います。
その方法でパッと思いつくのが「inet_addr」関数を使用する方法。 正しいIPアドレス文字列を渡せばそのアドレスの4バイト整数値が戻り値として返されますし、フォーマットが正しくなかったりすれば戻り値は INADDR_NONE になりますからね。 しかし、昔は私も使ってたこの方法、割と厄介な(?)問題を含んでいるので、ここに記しておきます。 まず、割と広く知られている問題が「255.255.255.255」を不正なアドレス文字列と判定してしまうこと。 というのも、アドレス 255.255.255.255 の4バイト整数表現は 0xFFFFFFFF であり、これは奇しくもエラー時の戻り値である INADDR_NONE と同じであるためです。 では「255.255.255.255」の場合だけ別に判定すればいいかというと、そう単純な問題ではなかったりします。 たとえば、「192.168.001.015」という文字列。 inet_addr 関数はもちろんこの文字列は正しいIPアドレスであると判定し、4バイト形式のアドレスを返します。 さて、普通に考えたらこの「192.168.001.015」は「192.168.1.15」と同じであると考えますよね? 単にゼロ埋めして桁数を3桁ずつにしただけですし。 しかし、実際は「192.168.001.015」は「192.168.1.15」とは違うアドレスであり、「192.168.1.13」と同じアドレス と判定されてしまうのです。 これは、inet_addr 関数のちょっと面倒な仕様によるもの。 inet_addr 関数は、ドット「.」区切りされた文字列のそれぞれの数字を、C言語の整数の記述と同じ仕様で解釈するのです。 つまり先頭が「0」で始まっていればその値は8進数であると解釈し、「0x」で始まっていれば16進数表記であると解釈します。 つまり、以下のアドレス表記はすべて正しいとして扱われ、「192.168.1.15」と同じアドレスと解釈されてしまうわけです。 ・「0xC0.0xA8.0x01.0x0F」(16進数) ・「0300.0250.01.017」(8進数) ・「192.0250.1.0x0F」(8進数、10進数、16進数の混在も可能) 16進数はともかくとして、桁合わせのつもりで先頭をゼロ埋めしただけで8進数と解釈されてしまうのは、想定していない場合が多いことでしょう。 さらに inet_addr は余計な(?)仕様がありまして、一般的な4つの数字の形式(「A.B.C.D」形式)だけでなく、3つの数字(「A.B.C」形式)やら2つ (「A.B」形式)、挙句には1つ(「A」形式)も受け取るということ。 inet_addr にかかれば以下の文字列も「192.168.1.15」と等しいアドレスと扱われます。・「192.168.271」 ・「192.11010319」 ・「3232235791」 もちろん、それぞれ8進数にしたり16進数にしたりも可能。 なんでも、この謎の仕様はWinsockのもととなっているBerkeleyソケット(UNIX系で使われてるソケット)の仕様と互換をとるためなのだそ うで。 このような仕様のために予想外の動作をしてもらっては困るので、IPアドレス文字列の正当性判定や4バイト整数形式アドレスへの変換は自前でやる必要があ りそうです。 PR |
プロフィール
HN:
はむぱい
職業:
ソフト作ったりしてる人
Twitter
カテゴリー
最新CM
[06/09 replica rolex oyster perpetual datejust]
[06/09 bracelets imitation cartier love]
[06/09 replica the oyster perpetual datejust]
[06/09 datejust rolex oyster perpetual]
[06/09 replica gold love bangle]
カレンダー
ブログ内検索
あ~いい漢字
|