2010-10-21 3 views
1

Работает на C#, я использую SharpPCap для получения сегментов из трассы winpcap.Как построить сообщение из сегментов tcp

Мне нужно перестроить все сообщения, отправленные и полученные по этой трассе.

В моей ситуации 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); 
       } 
      } 

Проблема с моим решением, когда клиент посылает два запроса в ряд. Я просто объединять два сообщения в одном. Если изменить

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.

Мне нужен способ правильного слияния сегментов для восстановления исходных сообщений. Я не могу полагаться на протокол, используемый для TCP.

Спасибо!

Edit: В Wireshark, когда вы делаете следовать протоколу TCP потока, это не обязательно знать протокол по протоколу TCP, но он может показать каждый запрос и ответ в различных цветах. Как это можно сделать? Я ищу ту же функциональность, потому что в моей ситуации никогда не будет второго запроса до получения ответа в потоке. Спасибо

ответ

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); 

Все три примера являются законными способами записи HTTP-запроса. Все трое могли выглядеть одинаково на проводе. Конечно, у последнего есть сильные шансы быть разными, даже если это означает одно и то же (представьте, что сон не является явным, но может быть вызван чтением файлов cookie с диска). Тем не менее последний может быть сложен в одну передачу, если конкретный TCP-сокет удерживается повторами в момент возникновения двух записей. Второй пример может отображаться как один пакет или два только на основе другой нагрузки на интерфейс (или параметры сокета, такие как CORK).