2014-01-23 2 views
0

Я использую следующий код для выполнения подключения к сокету tcp и отправки строки в IP. Но иногда в ответ, я не получаю весь файлTCP Socket получает только часть сообщения

 Socket m_socClient; 
     IPSelected ="1.1.2.3" 
       Port = "80" 
       string query ="My Query" 
       m_socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
       System.Net.IPAddress remoteIPAddress = System.Net.IPAddress.Parse(IPSelected); 
       System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, Port); 
       m_socClient.Connect(remoteEndPoint); 
       try 
       { 
        if (m_socClient.Connected) 
        {      
         var reQuestToSend = ""; 


          reQuestToSend = string.Format("POST /TMHP/Request HTTP/1.1\r\nHost:{0}\r\nContent-Length:{1}\r\n\r\n{2}", "edi-webtest.tmhp.com", Query270.Length, Query270); 
         byte[] bytesToSend = Encoding.ASCII.GetBytes(reQuestToSend); 
         byteCount = m_socClient.Send(bytesToSend, SocketFlags.None); 
         byte[] bytesReceived = new byte[3000]; 
    byteCount = m_socClient.Receive(bytesReceived, SocketFlags.None); 
         Response271 = Encoding.ASCII.GetString(bytesReceived); 

        } 
       } 
       catch (Exception ex) 
       { 
        EVCommon.Log(ex.Message); 

       } 
       finally 
       { 
        m_socClient.Disconnect(false); 
        m_socClient.Close(5000); 
       } 

Я думаю, что проблема с Byte [] bytesReceived = новый байт [3000]; Есть ли способ не кодировать это число 3000. Он работает большую часть времени, но для более длинных строк он получает только половину. Я хочу, чтобы он обрабатывал сообщения с переменным размером вместо задания размера байта до 30000 Спасибо

+0

Где код, который читает сокет? Вам нужно будет продолжать чтение до тех пор, пока сервер не закроет соединение, или вы не получите последний фрагмент, или не прочитайте байты, обозначенные заголовком Content-length, или ... используйте библиотеку HTTP, такую ​​как WebClient или HttpClient. – CodeCaster

+0

У меня нет доступа к серверному коду. Я уверен, что они получают всю строку. Поскольку до тех пор, пока они не получат полную строку, которая проходит проверку на своем конце, они не отвечают другой строкой. Проблема не в чтении. Его проблема с получением ответа – user575219

+0

Как @CodeCaster говорит - где код для чтения из сокета в arrayBeceived? –

ответ

4

Прочитано RFC 2616 Section 4.4. В нем рассказывается, как определить конец ответа сервера, чтобы вы знали, сколько байтов читать. Сначала вы должны сначала прочитать и обработать заголовки ответов сервера, чтобы узнать, как передаются остальные данные, если таковые имеются. Затем вы можете продолжать чтение из сокета соответственно, потенциально анализируя то, что вы прочитали, до тех пор, пока не будет достигнут конец ответа. Ваш текущий код чтения даже не подходит для удовлетворения этого требования.

Например (псевдо-код):

line = read a CRLF-delimited line; 

responseNum = extract from line; 
httpVer = extract from line; 

do 
{ 
    line = read a CRLF-delimited line; 
    if (line == "") break; 
    add line to headers list; 
} 
while (true); 

if (((responseNum/100) != 1) && 
    (responseNum != 204) && 
    (responseNum != 304) && 
    (request was not "HEAD")) 
{ 
    if ((headers has "Transfer-Encoding") && 
     (headers["Transfer-Encoding"] != "identity")) 
    { 
     do 
     { 
      line = read a CRLF-delimited line; 
      chunkLen = extract from line, decode hex value; 
      if (chunkLen == 0) break; 
      read exactly chunkLen number of bytes; 
      read and discard a CRLF-delimited line; 
     } 
     while (true); 

     do 
     { 
      line = read a CRLF-delimited line; 
      if (line == "") break; 
      add line to headers list, overwrite if exists; 
     } 
     while (true); 

     decode/transform read data based on headers["Transfer-Encoding"] values if more than just "chunked" 
    } 
    else if (headers has "Content-Length") 
    { 
     read exactly headers["Content-Length"] number of bytes 
    } 
    else if (headers["Content-Type"] == multipart/byteranges) 
    { 
     boundary = headers["Content-Type"]["boundary"]; 
     read and parse MIME encoded data until "--"+boundary+"--" line is reached; 
    } 
    else 
    { 
     read until disconnected; 
    } 
} 

if (((httpVer >= 1.1) && (headers["Connection"] == "close)) || 
    ((httpVer < 1.1) && (headers["Connection"] != "keep-alive"))) 
{ 
    disconnect; 
} 

Я оставляю это как упражнение для вас на самом деле осуществить это в вашем коде.

+0

Leoeau: Не могли бы вы показать мне несколько примеров? – user575219

+0

У вас есть * примеры. У вас есть запрос, который вы пытаетесь отправить, и ответ, который вы пытаетесь прочитать. – EJP

+0

Я мог бы попробовать и реализовать его. Но из 500 или 1000 транзакций в день я получаю эту проблему менее чем за 5 запросов. Так что 95% и более успешны. – user575219

Смежные вопросы