1

C# で作業しているため、SharpPCap を使用して winpcap トレースからセグメントを取得しています。

そのトレースで送受信されたすべてのメッセージを再構築する必要があります。

私の状況では、クライアントとサーバーの IP が同じになることはありません。クライアントのポートは必ずしも変更されません。

メッセージで使用されるプロトコルは、HTTP か、私が知らないカスタムのものである可能性があります。

それが私が現在行っている方法です:

            if (ipPacket.Protocol == IPProtocolType.TCP)
            {
                TcpPacket tcpPacket = (TcpPacket)ipPacket.PayloadPacket;

                Packet dataPacket = tcpPacket;
                while (dataPacket.PayloadPacket != null)
                    dataPacket = dataPacket.PayloadPacket;

                if (dataPacket.PayloadData.Length > 0)
                {
                    if (m_MessageContainer.IsEmpty()
                        || ((m_MessageContainer.Last().SourceIp.ToString() != ipPacket.SourceAddress.ToString())
                             && tcpPacket.Psh))
                    {
                        m_MessageContainer.Add(BuildMessage(ipPacket, tcpPacket));                      
                    }
                    m_MessageContainer.Last().AddData(dataPacket.PayloadData);
                }
            }

私のソリューションの問題は、クライアントが 2 つの要求を続けて送信する場合です。2 つのメッセージを 1 つにマージするだけです。私が変われば

if (m_MessageContainer.IsEmpty()
  || ((m_MessageContainer.Last().SourceIp.ToString() != ipPacket.SourceAddress.ToString())
       && tcpPacket.Psh))
 {
     m_MessageContainer.Add(BuildMessage(ipPacket, tcpPacket));                      
 }

if (m_MessageContainer.IsEmpty()
  || tcpPacket.Psh)
 {
     m_MessageContainer.Add(BuildMessage(ipPacket, tcpPacket));                      
 }

次に、メッセージが複数の tcp セグメントに分割され、フラグ psh がそれらの tcp セグメントの少なくとも 2 つに設定されている場合に問題が発生します。

セグメントを正しくマージして元のメッセージを再構築する方法が必要です。TCP で使用されるプロトコルに依存できません。

ありがとうございました!

編集: wiresharkでは、tcpストリームをたどると、必ずしもtcp経由のプロトコルを認識しているわけではありませんが、各リクエストとレスポンスを異なる色で表示できます。どうやってそれができるのですか?私の状況では、ストリームで応答が受信される前に 2 番目の要求がないため、同じ機能を探しています。ありがとう

4

1 に答える 1

0

元のアプリケーション コードがどのようにソケットに書き込まれたかは、ネットワーク上のストリームを観察するだけではわかりません。特定の状況下で表示される可能性のあるヒントを使用することについて話しているが、それらに依存することはできません (発見したように)。

write(sock, "GET / HTTP/1.0\r\n\r\n", len);

write(sock, "GET / HTTP/1.0\r\n", len);
write(sock, "\r\n", 2);

write(sock, "GET / HTTP/1.0\r\n", len);
sleep(1);
write(sock, "\r\n", 2);

これらの 3 つの例はすべて、HTTP クエリを記述する正当な方法です。3 つすべてがワイヤ上で同じように見える可能性があります。確かに、最後のものは同じことを意味していても、異なる可能性が高いです (スリープは明示的ではなく、おそらくディスクから Cookie を読み取ったことが原因であると想像してください)。それでも、2 つの書き込みが発生した時点で特定の TCP ソケットが再試行によって保留されている場合、最後の 1 つが 1 つの送信に折りたたまれる可能性があります。2 番目の例は、インターフェイス (または CORK などのソケット オプション) の他の負荷に基づいて、1 つまたは 2 つのパケットとして表示される場合があります。

于 2010-10-22T00:20:12.537 に答える