2009-05-03 4 views
0

소켓을 사용하여 간단한 SNPP (Simple Network Paging Protocol) 클라이언트를 작성하려고합니다. 서버 간의 작은 불일치를 제외하면 모든 것이 잘 작동하는 것 같습니다.소켓에서 단일 버퍼로 청크 데이터 수신

명령을 보낼 때 일반적으로 데이터의 단일 청크 인 응답을 읽어야합니다. 그러나 Sprint의 SNPP 서버는 두 부분으로 응답을 보냅니다. 데이터의 첫 번째 청크는 상태 코드의 첫 번째 숫자입니다. 두 번째 청크는 나머지 부분입니다. 나는 "220 게이트웨이 준비"응답을받지하려고 할 때 예를 들어,이 같은 도착 :

2 

내가 나머지 검색하는 또 다른 빈 명령을 보낼 수 있습니다 순간을 위해

20 Gateway ready 

을 내가 사용하고 있습니다 :

byte[] buffer = new byte[256]; 
socket.Receive(buffer); 

어떻게 내가 데이터의 각 청크에 대해 별도의 버퍼를 할당하지 않고 명령을 실행 한 후 사용 가능한 모든 데이터를받을 수 있는지 확인 할 수 ?

답변

3

: 그것은 함께

using (var resultStream = new MemoryStream()) 
{ 
    const int CHUNK_SIZE = 2 * 1024; // 2KB, could be anything that fits your needs 
    byte[] buffer = new byte[CHUNK_SIZE]; 
    int bytesReceived; 
    while ((bytesReceived = socket.Receive(buffer, buffer.Length, SocketFlags.None)) > 0) 
    { 
     byte[] actual = new byte[bytesReceived]; 
     Buffer.BlockCopy(buffer, 0, actual, 0, bytesReceived); 
     resultStream.Write(actual, 0, actual.Length); 
    } 

    // Do something with the resultStream, like resultStream.ToArray() ... 
} 
+0

모든 크기의 청크를 처리하기 때문에이 솔루션이 마음에 들었습니다. 그러나 첫 번째 응답을받은 후 응용 프로그램이 새 데이터가있을 때까지 응답을 중지합니다. 디버거는 while 조건에서 멈춘다는 것을 보여줍니다. –

1

Socket.Available 속성을 검사하여 Receive를 다시 호출해야하는지 확인하십시오.

0

나는 귀하의 질문을 이해한다고 생각합니다. Socket.Receive의이 오버로드로 정수 배치를 지정하여 데이터 배치를 시작할 수 있습니다. 첫 번째 호출에서 예제처럼 1 바이트를 얻은 경우 오프셋 1을 사용하여이 오버로드를 호출하고 동일한 버퍼를 사용할 수 있습니다.

0

Socket.Receive은 수신 된 바이트 수를 정수로 반환합니다. 이 번호가 1인지 확인한 다음 Receive으로 다시 전화하십시오. 나는이 같은 데이터를 읽는 것이 좋습니다 청크 응답에 대한

byte[] buffer = new byte[256]; 
int len = socket.Receive(buffer); 

if (len == 1) 
    socket.Receive(buffer, 1, buffer.Length - 1, SocketFlags.None); 
-1

모든,

웹 서버가 "덩어리"에 데이터를 전송하고 각 덩어리를 앞에 length (16 진수 값을 나타내는 문자열).

청크 크기 [] 청크 정보] 청크 데이터

예 : 15 바이트 청크로 :

F; 123456789ABCDEF

소켓에서 HTTP 데이터를 수신 할 때 가장 큰 문제는 읽을 데이터의 양을 결정하는 것입니다. 사용 가능한 데이터를 모두 받았고 Recieve 메서드를 다시 호출하면 Recieve 메서드는 원격 소켓이 전송 될 때까지 차단됩니다 더 많은 데이터는 HTTP/1.0 연결에 대해 결코 발생하지 않습니다.

소켓을 감싸는 리더를 구현해야합니다. 버퍼에 데이터를 받아야하고 13을 읽었을 때까지 버퍼의 내용을 읽는 "ReadLine"메서드를 제공해야합니다. (CRLF)

관련 문제