2014-10-24 2 views
0

C++ 비 차단 recv를 통해 데이터를 수신하고 모든 것이 예상대로 8 바이트 페이로드로 작동하지만 9 바이트 이상을 수신하려고 시도 할 때 recv는 -1을 반환합니다. errno는 0입니다.8 바이트 이상을 수신 할 때 UDP recv가 실패 함

다음은 내 코드의 관련 부분입니다. init-fcns의 반환 값을 확인하고 확인합니다. 단편을 생략하면됩니다.

초기화 코드 :

WSADATA w; 
HANDLE soc, sem; 
SOCKADDR_IN addr; 

err = WSAStartup(0x0202, &w); 
soc = socket(AF_INET, SOCK_DGRAM, 0); 
memset((void *)&addr, '\0', sizeof(addr)); 
addr.sin_family = AF_INET; 
addr.sin_port = htons(50001); 
addr.sin_addr.s_addr = ADDR_ANY; 

sem = CreateEvent(nullptr, false, false, nullptr); 
WSAEventSelect(soc, sem, FD_READ); 

수신기 스레드 :

char buf[10000]; 
int bytes_read = 0; 

while (true){ 
    WSAWaitForMultipleEvents(1, enqueue_sem, false, WSA_INFINITE, false); 

    bytes_read = recv(soc, buf, sizeof(buf), 0); 
    cout << bytes_read << ":" << strerror(errno) << endl; 
    cout << buf << endl; 
} 

내가 9 바이트 이상을 보내고있다, 패킷이 괜찮 (whireshark를 통해 확인), 심지어 처음 8 바이트는 buf에 쓰여 지지만, 이후의 모든 바이트는 손실됩니다.

은 사전에 감사

+1

8 바이트는 의심스럽게 64 비트 변수처럼 들립니다. 주소 대신 버퍼에 변수를 사용하거나 그 반대의 경우도 있습니다. –

+1

@ Dwayne의 덧글에서 확장 : 당신의 실제 코드'buf'는'char' 배열이 아니라'char *'포인터입니다. 'sizeof (buf)'는 가리키는 버퍼의 크기가 아니라 포인터의 크기입니다. –

+0

정말로 의심 스럽지만, buf가 8 바이트 만이라도 recv는 sizeof (buf)까지 모든 데이터를 복사하고 나머지 부분은 오류없이 버려야합니다. 권리? 더 이상의 아이디어? Btw .: buf는 char buf [10000];로 정의됩니다. – Chili

답변

2

내 추측은 당신의 코드는 당신이 우리 보여주는 것과 약간 다른 모습이다 : sizeof(buf) 10000되지 않을 것이 경우

char global_buf[10000]; 
char *buf = global_buf; 
recv(soc,buf,sizeof(buf),0); 

을하지만, 포인터 대신 8 (크기 64 비트 플랫폼에서), 8 바이트 만 수신 할 수있는 이유를 설명합니다.

+0

힌트를 보내 주셔서 감사 드리며 @Dwayne, 실제로 문제가되었지만 여전히 만족스럽지 않습니다. recv에서보다 정확한 오류 코드를 얻을 수있는 가능성이 -1 이상입니까? – Chili

+0

[documentation for recv] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121 (v = vs.85) .aspx)를 참조하십시오. 그것은 당신이'WSAGetLastError'를 호출함으로써 더 자세한 에러를 얻는다 고 말합니다. 귀하의 경우에 이것은 아마도 'WSAEMSGSIZE'를 초래할 것입니다 : "메시지가 너무 커서 지정된 버퍼에 맞출 수없고 잘렸다". –

+0

완벽한, 감사합니다. – Chili