3

IP パケットの「パーサー」をいじっていたときに、何かおかしなことに気付きました。

IP アドレスの解析に関しては、C# で

private uint srcAddress; 
// stuff
srcAddress = (uint)(binaryReader.ReadInt32());

トリックを行うので、このVB.Netの同等物と思うでしょう

Private srcAddress As UInteger
'' stuff
srcAddress = CUInt(binaryReader.ReadInt32())

もトリックを行うでしょう。そうではありません。これ :

srcAddress = reader.ReadUInt32()

ただし、します。

発見するのに少し時間がかかりましたが、何を発見しましたか? どうしてこれなの ?

4

1 に答える 1

5

VB.NET は既定で、C# が既定で実行しないことを行います。数値のオーバーフローを常にチェックします。そして、それあなたのコードでトリガーされ、最後のビットが 0 ではなく 1 である IP アドレスは負の数を生成し、UInteger に変換できません。正の 32 ビット数のみを格納できるデータ型。

C# にもこのオプションがあります。コードでcheckedキーワードを明示的に使用する必要があります。または、VB.NET プロジェクトがデフォルトでオンになっているのと同じオプションを使用します: [プロジェクト + プロパティ]、[ビルド] タブ、[詳細設定]、[算術オーバーフロー/アンダーフローのチェック] チェックボックスをオンにします。VB.NET プロジェクトの同じオプションは、「整数オーバーフロー チェックを削除する」という名前で、既定ではオフになっています。

これらのデフォルトが言語の構文にもどのように影響したかに注意してください。C# では、値を互換性のない値型に変換するキャストを記述する必要があります。VB.NET では必要ありませんが、実行時チェックによってトラブルを回避できます。これは非常に厄介な問題であり、オーバーフローは非常に悪い結果をもたらす可能性があります。あなたの場合はそうではありません.IPアドレスは実際には署名されていない数値です.

IP アドレスに関するもう 1 つの癖を覚えておいてください。ソケットは、LSD とビッグエンディアン プロセッサを搭載した Unix マシンで最初に発明されました。通常、適切な順序でアドレスを取得するには、IPAddress.NetworkToHostOrder() を使用する必要があります。符号付き整数型を引数として取るオーバーロードのみがあります。したがって、ReadInt32() を使用することは実際には正しく、IPv4 アドレスであると仮定すると、それを直接 NetworkToHostOrder() に渡します。オーバーフローの心配はありません。

于 2014-06-07T16:04:01.427 に答える