2013-08-05 1 views
0

웹 프록시를 작성 중이며 ASCII 텍스트로 변환 할 수있는 웹 페이지와 잘 작동합니다. 그러나 이진 데이터가있는 페이지를 보려고하면 (Youtube.com은 내가 사용하고있는 것입니다.), 메모리 누수가 발생하고 같은 수의 문자가 문자열 끝에 반복해서 반복됩니다. 클라이언트에게 보낼 것입니다 (그리고 그들이 분명히해서는 안되는 다른 장소에 나타납니다).C 소켓 이진 데이터로만 메모리 누수가 발생합니다.

다음은 내 코드의 관련 부분입니다. SendHTTPResponse는 프록시를 사용하여 클라이언트에게 웹 페이지의 응답을 보내고 올바르게 작동하는 함수입니다.

아무도 통찰력이 있습니까?

int numBytes; 
char temp[3000]; 
memset(temp, '\0', 3000); 
numBytes = Read(internetSocket, temp, 2999); 
while (errno = 0, numBytes > 0 || errno == EINTR) 
{ 
    SendHTTPResponse(socket, temp, numBytes); 
    memset(temp, '\0', 3000); 
    numBytes = Read(internetSocket, temp, 2999);  
} 
+0

이 질문에 대답하기에 충분한 정보 또는 코드가 없습니다. 디버깅을하고 범위를 좁혀 야합니다. –

+0

numBytes == 0을 유효한 반환 값으로 사용할 필요가 없습니다. 즉, 버퍼에 아무 것도 없었지만 스트림이 아직 열려 있고 계속 읽으려고해야합니까? –

+4

errno = 0, numBytes> 0 ???? 그게 뭐야? 왜 그런 콤마 연산자를 사용하고 있습니까? 그리고 왜 당신은 errno를 0으로 설정하고 있습니까? –

답변

1

질문에 대답하기 위해이 코드에는 메모리 누수가 없습니다.

메모리 누수가이 문제와 관련이 있다고 생각할 이유가 없습니다.

그러나 코드가 잘못되었습니다. errno을 설정해서는 안되며, -1을 반환하지 않는 한 테스트하지 말아야합니다. 읽어야합니다

while ((numBytes = Read(socket, temp, sizeof temp)) > 0 || numBytes == -1 && errno == EINTR) 
{ 
    SendHTTPResponse(socket, temp, numBytes); 
} 

당신은 memset() 호출을 필요로하지 않으며, 당신은 뒤에 널 (null)에 대한 공간을 확보 할 필요가 없습니다, SendHTTPResponse() 당신이 그것을 통과 길이의 적절한 통지를합니다 제공. 확실히 후행 null 자체를 찾지 않아야합니다.

그리고 3000은 매우 이상한 버퍼 크기입니다. 나는 8192를 사용할 것이다.

+0

'numBytes'가 -1이면'SendHTTPResponse()'는 전송할 데이터가 없으므로 호출하지 말아야하지만'errno'가'EINTR' 일 때 읽기를 계속하려면'Read()'를 다시 호출해야합니다. 'do/while' 루프를 대신 사용하고'Read()'가 실제로 실패 할 때'break'를 사용합니다. –

0

이것은 귀하의 문제에 대해 잘 알고있는 추측에 불과합니다. 다른 사람들이 말했듯이, 오류를 찾기에 충분한 정보를 게시하지 않았습니다.

이진 데이터와 텍스트 데이터의 가장 큰 차이점은 (EDIT, 감사 EJP)이 null ('\ 0') 바이트를 포함 할 수 있다는 것입니다. 문자열 함수 (예 : strlen())를 사용하는 경우 문자열 끝으로 해석하여 데이터를 놓치게됩니다.

+1

* former *는 null 바이트를 포함 할 수 있습니다. – EJP