Boost asio는 아무 이유없이 코드 0으로 종료됩니다. 문제가있는 문으로 해결 된 후 중단 점 설정

다니엘

boost asio를 사용하여 TCP 서버-클라이언트 쌍을 작성하고 있습니다. 매우 간단하고 동 기적입니다.

서버는 TCP를 통해 데이터 패킷을 전송하는 함수에 대한 여러 재귀 호출을 통해 많은 양의 이진 데이터를 전송해야합니다. 클라이언트는 소켓에서 들어오는 패킷을 읽는 재귀 함수를 통해 데이터를 읽고 추가하면서 아날로그를 수행합니다.

그러나이 데이터를받는 동안 대부분 (약 80 %) 클라이언트는 항상 읽기 호출 중 하나 (아래 참조) 전에 갑자기 재귀를 중지합니다. 재귀 후에 다른 명령문과 함수 호출이 여러 개 있다는 점을 감안할 때이를 수행 할 수 없어야합니다.

size_t bytes_transferred = m_socket.read_some(boost::asio::buffer(m_fileReadBuffer, m_fileReadBuffer.size()));

m_fileReadBuffer는 크기가 4096 인 char의 boost :: array입니다 (다른 버퍼 형식도 시도했지만 성공하지 못했지만).

왜 이런 일이 발생하는지 추론 할 수있는 방법은 전혀 없습니다.

  • 프로그램이 즉시 종료되므로 read_some 문 이후에 발생해야하기 때문에 read_some에 오류 코드를 전달하고 오류 메시지를 읽을 수 없습니다.
  • 예외가 발생하지 않습니다.
  • 컴파일 / 런타임에 오류 또는 경고 없음
  • 재귀 함수 안에 중단 점을 넣으면 문제가 발생하지 않습니다 (전송이 성공적으로 완료 됨).
  • 전송 후 중단 점을 넣거나 전송 후 while 루프에서 실행을 트랩하면 문제가 발생하지 않고 잘못된 징후가 없습니다.

또한 서버가 항상 모든 데이터를 성공적으로 전송한다는 점에 유의하는 것이 중요합니다. 게다가 문제는 항상 전송이 끝날 때 발생합니다. 8000 바이트를 보낼 수 있고 약 6000 또는 7000 바이트가 전송되면 종료되고 8000000 바이트를 보낼 수 있으며 7996000 바이트와 같은 경우 종료됩니다. 전송되었습니다.

필요한 모든 코드를 제공 할 수 있지만 문제가 어디에 있는지 알 수 없습니다. 다음은 클라이언트의 재귀 읽기 기능입니다.

void TCP_Client::receive_volScan_message()
{
    try
    {
        //If the transfer is complete, exit this loop
        if(m_rollingSum >= (std::streamsize)m_fileSize)
        {
            std::cout << "File transfer complete!\n";
            std::cout << m_fileSize << " "<< m_fileData.size() << "\n\n";               

            return;
        }

        boost::system::error_code error;        

        //Transfer isn't complete, so we read some more        
        size_t bytes_transferred = m_socket.read_some(boost::asio::buffer(m_fileReadBuffer, m_fileReadBuffer.size()));

        std::cout << "Received " << (std::streamsize)bytes_transferred << " bytes\n"; 

        //Copy the bytes_transferred to m_fileData vector. Only copies up to m_fileSize bytes into m_fileData
        if(bytes_transferred+m_rollingSum > m_fileSize) 
        {
            //memcpy(&m_fileData[m_rollingSum], &m_fileReadBuffer, m_fileSize-m_rollingSum);
            m_rollingSum += m_fileSize-m_rollingSum;
        }
        else
        {
           // memcpy(&m_fileData[m_rollingSum], &m_fileReadBuffer, bytes_transferred);
            m_rollingSum += (std::streamsize)bytes_transferred;  
        }                     

        std::cout << "rolling sum: " << m_rollingSum << std::endl;

        this->receive_volScan_message();
    }
    catch(...)
    {
        std::cout << "whoops";
    }                
}

제안으로 클라이언트와 서버 모두에서 재귀 루프를 for 루프로 변경해 보았습니다. 어떻게 든 문제가 지속됩니다. 유일한 차이점은 이전에 언급 한 read_some 호출 전에 0을 종료하는 대신 다른 for 루프 패스를 실행하기 바로 전에 for 루프 블록 중 하나의 끝에서 0을 종료한다는 것입니다.

편집 : IDE에서 디버그 모드로 클라이언트를 빌드 할 때마다 오류가 발생하지 않습니다.

다니엘

나는 문제를 완전히 이해하지 못했지만 완전히 고칠 수 있었다.

문제의 원인은 클라이언트 에서 서버 메시지가 아직 도착하지 않은 경우boost::asio::read 호출 이 코드 0으로 메인 종료를 생성했다는 것 입니다. 즉, 간단한

while(m_socket.available() == 0)
{
    ;
}  

모든 읽기 호출이 문제를 완전히 방지하기 전에. 디버그 및 릴리스 모드 모두.

이 함수는 읽을 것이있을 때까지 차단해야하며 오류가 발생하더라도 0을 반환해야하기 때문에 매우 이상합니다.

m_readBuffer읽기 호출이 발생할 때마다 아무것도 초기화되지 않았기 때문에 디버그 / 릴리스 불일치가 발생했다고 생각합니다 . 이로 인해 read호출 일종의 침묵 오류를 반환했습니다. 디버그시 초기화되지 않은 변수는 자동으로로 설정되어 NULL은밀하게 문제를 해결합니다.

전송 while 루프를 추가 하여 문제를 방지하는 이유를 모르겠습니다 . m_readBuffer가 설정되고 여러 번 성공적으로 사용 된 후 일반적으로 전송 끝날 때 발생하는 이유도 아닙니다 .

게다가, 이런 유형의 "크래시"를 본 적이 없었습니다. 프로그램이 오류나 예외없이 임의의 위치에서 코드 0으로 종료되는 경우입니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관