3

生のソケットをリッスンしてコードを介して Web サイトからの応答を読み取ろうとしていますが、これまでのところ、実際に関心のある着信応答ではなく、コンピューターから送信された発信要求しか読み取ることができませんでした。受信した応答を読み取るにはどうすればよいですか?

編集: Wireshark を使用すると、探しているデータが TCP 経由で送信されていることがわかりました。

Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Unspecified);
IPAddress localIP = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
listener.Bind(new IPEndPoint(localIP, 0));
byte[] invalue = new byte[4] { 1, 0, 0, 0 };
byte[] outvalue = new byte[4] { 1, 0, 0, 0 };
listener.IOControl(IOControlCode.ReceiveAll, invalue, outvalue);
while (true)
{
    byte[] buffer = new byte[1000000];
    int read = listener.Receive(buffer);
    if (read >= 20)
    {
        Console.WriteLine("Packet from {0} to {1}, protocol {2}, size {3}",
            new IPAddress((long)BitConverter.ToUInt32(buffer, 12)),
            new IPAddress((long)BitConverter.ToUInt32(buffer, 16)),
            buffer[9],
            buffer[2] << 8 | buffer[3]
        );
    }
}
4

3 に答える 3

6

ポート 0 は、彼がすべてのポートでリッスンすると言います。代わりに、ProtocolType.Unspecified を ProtocolType.IP に設定する必要があると思います。

new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Raw); msdnで読んだものからのipv6用です。ProtocolType.IPは、生のソケットを使用したipv4でサポートされています。

また、これはコネクションレスソケットだと思いますか?そうでない限り、Reciveallは実際には影響しません。IPヘッダーの後にいる場合は、次のようなコードを設定することで取得できます:

Socket sck = new Socket( AddressFamily.InterNetwork  , SocketType.Raw  , ProtocolType.IP);
   sck.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);  

お役に立てれば :)

于 2011-01-30T12:51:57.420 に答える
1

今日、まったく同じことをする方法を考えていました!これが機能するようになった私のコードです。これを機能させるための功績は、ProtocolType.IPを提案した仲間の回答者「Tom Erik」によるものです。

    static void Main(string[] args)
    {
        // Receive some arbitrary incoming IP traffic to an IPV4 address on your network adapter using the raw socket - requires admin privileges
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
        IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList
            .Where((addr) => addr.AddressFamily == AddressFamily.InterNetwork)
            .Where((addr) => addr.GetAddressBytes()[0] != 127)
            .First();
        s.Bind(new IPEndPoint(ipAddress, 0));
        byte[] b = new byte[2000];
        EndPoint sender = new IPEndPoint(0, 0);
        int nr = s.ReceiveFrom(b, SocketFlags.None, ref sender);
    }
于 2012-09-06T23:22:57.467 に答える
1

基本的に同じ raw ソケット設定を使用して、C++ プログラムで同様の問題が発生しました。私の場合、デバッグ ビルドでは受信パケットを確認できますが、リリース ビルドでは確認できません。両方のビルドで発信パケットが見られます。このプログラムではパケットを送信していません。

Win7 x64 で VS2008 ネイティブ C++ を使用してビルドしています。

私の問題はファイアウォールにありました。プロジェクトがVSで作成されたとき、プロジェクトビルドによるネットワークアクセスのためにファイアウォールに「許可」エントリを配置したようですが、プログラムのデバッグビルドに対してのみです。

リリース ビルド用に別のエントリを追加する必要があり、これにより着信パケットが許可されました。Win7 での高度なファイアウォール設定により、特定のプロトコルがブロックされることもあるため、受信メッセージが部分的にしか表示されない場合は、プログラムのエントリの設定を確認してください。

于 2011-02-26T15:33:41.600 に答える