2014-07-25 8 views
0

의 크기에 메시지를 붙이는, 나는 여기에이 코드를 가지고 :내가 뭔가 서버 - 클라이언트가 관련 쓰고 메시지

readyRead() 신호가 서버에 의해 방출 될 때마다 데이터를 읽어
char serverReceiveBuf[65536]; 
client->read(serverReceiveBuf, client->bytesAvailable()); 
handleConnection(serverReceiveBuf); 

. 대기 시간이 없기 때문에 로컬 네트워크에서 테스트 할 때 bytesAvailable()을 사용하면 문제가 없지만 프로그램을 배포 할 때 handleConnection() 전에 전체 메시지가 수신되도록하고 싶습니다.

나는 이것을 할 방법을 생각하고 있었지만, readwrite은 문자 만 받아들이므로 한 문자로 보낼 수있는 최대 메시지 크기 표시기는 127입니다. 최대 크기는 65536이 되길 원합니다. 메시지 크기 크기의 변수를 먼저 가지고 있다고 생각할 수 있습니다.

나는 같이하는 코드 재 :

char serverReceiveBuf[65536]; 
char messageSizeBuffer[512]; 
int messageSize = 0, i = 0; //max value of messageSize = 65536 
client->read(messageSizeBuffer,512); 
while((int)messageSizeBuffer[i] != 0 || i <= 512){ 
    messageSize += (int) messageSizeBuffer[i]; 
    //client will always send 512 bytes for size of message size 
    //if message size < 512 bytes, rest of buffer will be 0 
} 
client->read(serverReceiveBuf, messageSize); 
handleConnection(serverReceiveBuf); 

을하지만 존재하는 경우 나는 더 우아한 솔루션을하고 싶습니다.

+0

내 요점은 코드가 작동하고 나는'됨 bytesAvailable을()'를 사용 제대로 작동하지 않습니다 알고 나는'byteAvailable()' – Lighthat

+0

@Kuba을 사용하지 않고 작동하도록하는 방법을 알아 내려고합니다 나는 그것이 문자 그대로 왜이 질문을하고 있는지 알고 있습니다. 전체 질문 (내가하지 않았다고 가정)을 읽지 않았다면 메시지 크기를 전송하는 대안을 시도했지만 그것은 번거롭고 쉽게 처리 할 수있는 방법이 있는지 알고 싶었습니다. 'byteAvailable()'을 사용하는 것이 좋지 않은 행을 놓친 경우, 나는 당신을 위해 그것을 인용 할 수있다. "그러나 프로그램을 배포 할 때 handleConnection()을 수행하기 전에 전체 메시지가 수신되는지 확인하려고합니다." – Lighthat

+0

당신은 ** 단지 ** message size *를 결정하지 않고 ** 얼마나 많은 데이터를 읽을 수 있는지를 결정하기 위해'bytesAvailable'을 사용해야 만합니다. * :) 당신은 ** 또한 ** 메시지 크기를 보내야합니다. 당신은 ** 또한 ** bytesAvailable' * 이전 *을 확인하여 메시지 크기를 읽어야합니다. 메시지 크기는 2 또는 4 바이트가 될 수 있지만 읽는 데 필요한 바이트 수보다 적을 수 있습니다. [이 답변] (http://stackoverflow.com/a/24541844/1329652) . –

답변

1

이것은 전송할 스트림을 통해 메시지를 보낼 때 매우 보편적 인 기술입니다 메시지 페이로드 전에 고정 크기 헤더. 이 머리글은 많은 다른 정보를 포함 할 수 있지만 항상 페이로드 크기를 포함합니다. 가장 간단한 경우, 최대 페이로드 크기가 65535 (또는 충분하지 않은 경우 uint32_t) 인 경우 uint16_t으로 인코딩 된 메시지 크기를 보낼 수 있습니다. ntohshtons을 사용하여 바이트 순서를 처리해야합니다.

uint16_t messageSize; 
client->read((char*)&messageSize, sizeof(uint16_t)); 
messageSize = ntohs(messageSize); 
client->read(serverReceiveBuf, messageSize); 
handleConnection(serverReceiveBuf); 
+0

이렇게하면 문제가 발생합니다. 'client-> read ((char *) & messageSize, sizeof (uint16_t));를 사용할 때, 클라이언트에 의해 보내진'messageSize'가'sizeof (uint16_t)'보다 더 작다면 (바이트 단위로) 서버가 충돌합니다. 'sizeof (uint16_t)'를 1로 바꾸면 잘 돌아갑니다. 나는 클라이언트가'char * bytes ((char *) & messageSize); '라는 메시지를 prepending하고 있는데,'sizeof (uint16_t)'와 같은 수의 바이트를 항상 차지할 수있는 방법이있다. '? – Lighthat

0

바이트 스트림에 대한 읽기 및 쓰기 작업. 바이트가 문자 또는 다른 형식의 데이터이면 문제가되지 않습니다. 주소를 char *로 변환하고 4 바이트를 전송하여 4 바이트 정수를 보낼 수 있습니다. 수신 측에서는 4 바이트를 int로 캐스트합니다. (기계가 다른 유형이라면 엔디안 문제가 생길 수 있습니다. 바이트를 int로 재배치해야합니다 .htl과 그 사촌 참조)

관련 문제