2011-10-11 3 views
4

부스트 1.45 ASIO를 사용하여 Windows와 Mac에서 모두 실행되는 응용 프로그램에서 일부 소켓 연결을 처리합니다. Windows에서 다음 코드는 오류를 발생시키지 않으며 소켓은 완전히 닫힙니다. Mac의 경우 종료 및 종료 기능을 모두 주석 처리하면 "잘못된 파일 설명자"오류가 발생합니다. 이 코드를 호출하기 전까지는 소켓이 정상적으로 작동합니다. 그러나 종료 또는 닫기를 호출하자마자 오류가 발생합니다. 어떤 아이디어가 계속 될 수 있습니까? 이 작업을 수행하는 좋은 이유가없는 한잘못된 파일 기술자 닫기 부스트 소켓

if(socket.is_open()) 
{ 
    socket.shutdown(socket.both); 
    socket.close(); 
} 
+0

이 코드 스 니펫의 의도를 분명히 알 수 있다면 도움이 될 것입니다. 일반적으로'~ socket()'dtor는 기본 네이티브 디스크립터 유형을 닫는다. 명시 적으로 닫는 이유가 있습니까? –

+0

나는 소켓을 닫아야한다고 생각했다.이 오류는 분명히 (오류 자체 외에) 어떤 문제도 일으키지 않는 것처럼 보이기 때문에 소켓을 명시 적으로 닫을 필요가 없다면 행복하게 그게 내 인생과 함께 이동하고 이동하십시오. 그래서 명확히하기 위해 종료 또는 종료를 호출하지 않아도됩니까? –

+0

답변을 –

답변

1
if(socket.is_open()) 
{ 
    socket.shutdown(socket.both); 
    socket.close(); 
} 

, 나는 socket::~socket() 소멸자가 기본이되는 기본 파일 기술자를 종료시키는 것이 좋습니다. 설명자 누수가 염려되는 경우 valgrind과 같은 도구를 사용하여 프로그램을 분석하십시오.

+0

오류를 그냥 무시하지 않습니까? – Nemo

+0

이것은 실제로 오류를 무시하지 않습니다. asio 라이브러리는 디스크립터의 기본 유형을 추상화하고 자원 누출을 방지하기 위해 명시 적으로 닫을 필요가 없습니다. 프로그램 이중 닫기 설명자에 버그가있는 경우 다른 곳에서 발생할 가능성이 큽니다. –

+0

버그는 다른 곳에 있을지 모르지만 오류는 여기에서 발생합니다 ... 그리고 부스트 사람들은 소멸자로부터 예외를 던지지 않을 것이라고 확신합니다. 그래서 당신의 제안은 문제를 고치기보다는 문제를 무시하는 것입니다. (close()에서 오류를 감지 할 수없는 이유는 소멸자에 의존하는 것이 일반적으로 IMO 스타일이 아니기 때문입니다.이 경우 문제가 무엇이든간에 실제 문제는 확실히 무시됩니다.) – Nemo

0

나는 똑같은 문제가 있었다. 윈도우에서는 모든 것이 괜찮 았고, 리눅스에서는 소켓 상태 인 IIRC에 따라 예외가 던져졌다.

Sam의 대답에 대한 대안은 더미 error_code를 사용하여 예외가 발생하면 자동으로 무시하는 것입니다. asio 설명서에서 closeshutdown 오버로드를 참조하십시오.

7

"잘못된 파일 설명자"가 close 인 경우 대개 해당 설명자가 이미 닫혔다는 의미입니다. 이것은 종종 프로그램의 완전히 무관 한 일부 섹션에서 이중 닫기 버그로 인해 발생합니다.

이러한 버그는 전염 될 수 있습니다. 프로그램이 같은 디스크립터를 두 번 닫고 중간에 다시 할당되면 두 번째 close은 관련이없는 개체의 설명자를 그 아래에서 닫습니다. 그리고 나서 해당 객체가 해당 디스크립터를 닫을 때 실제로 다른 객체의 디스크립터를 닫을 수 있습니다 ... 마지막으로 한 줄의 마지막 디스크에 "잘못된 파일 설명자"오류가 발생할 때까지 계속됩니다.

이것은 (a) 설명자가 전역 상태이고 (b) open/socket/etc에 대한 호출이 필요하다는 부작용입니다. 사용되지 않은 가장 낮은 번호의 디스크립터를 할당하십시오.

이것을 디버그하는 유일한 방법은 strace (Linux의 경우) 또는 dtrace (Mac의 경우)과 같은 도구를 사용하여 모든 파일 설명 자의 생성 및 삭제를 모니터링하는 것입니다. (글쎄, 어쩌면 유일한 방법은 아니었다.) openclose에 대한 모든 호출을 가로 채서 어떤 설명자를 이중 닫는지를 파악하기 위해 해커 LD_PRELOAD 해커를 작성했다. 두 번째 닫기가 다른 스레드에서 사용중인 설명자를 누크했기 때문이다. ..)

행운을 빈다.

관련 문제