2009-08-10 4 views
0

asio를 사용하는 데 문제가 있습니다. 내 클라이언트/서버 응용 프로그램은 동기식 통신 만 필요합니다. 그래서 부스트 홈페이지의 싱크로 예제를 사용하여 데이터를 보내고받는 두 가지 절차를 설정했습니다. 코드는 다음과 같습니다.Boost.Asio 동기식 통신

이 절차는 부스트 예제에서 추출한 코드 줄에 대한 래퍼입니다. 내 테스트 응용 프로그램에서

, 클라이언트는

std::string szDate; 
vReceive(socket, szDate); 
vSend(socket, std::string("Chop Suey!")); 
vReceive(socket, szDate); 
vSend(socket, std::string("Halo")); 

호출하고 서버는

std::string message = make_daytime_string(); 
std::string szReceived; 
vSend(socket, message); 
vReceive(socket, szReceived); 
vSend(socket, message); 
vReceive(socket, szReceived); 

그냥 기능을 테스트하기 위해 호출합니다. 문제는 첫 번째 정보 교환 후에 두 응용 프로그램이 모두 멈추는 것입니다. 이는 다음과 같이 표현했습니다 : picture. 클라이언트 측의 vReceive() 프로 시저가 완료되지 않았습니다. vSend()이 서버 측에서 완료됩니다. 그래서, 아무도 어떤 생각을 가지고 있습니까? 무엇이 잘못 될 수 있습니까?

누군가가 문제를 복제하기를 원한다면 원본 소스를 동일한 서버에 업로드했습니다.이 서버의 그림은 asio_problem.rar 파일에 있습니다 (새 회원으로 게시물 당 하나의 하이퍼 링크가있을 수 있습니다).

미리 감사드립니다. 다니엘.

답변

1

나는 당신의 문제가 여기에있다 생각 :

for (;;){ 
    /* snipped */ 

    if (error == boost::asio::error::eof) 
    break; // Connection closed cleanly by peer. 
    else if (error) 
    throw boost::system::system_error(error); // Some other error. 

    /* snipped */ 
} 

당신은 연결 닫을 때까지 무한 (루프의 탈옥하는 유일한 방법은 소켓에서 EOF 오류가 발생하는 경우입니다) 반복하지만, vSend된다 소켓을 절대로 닫지 않습니다. 즉, 고객의 vReceive은 영원히 기다리고 항상 더 많은 데이터를 기다리고 있습니다. vSendsocket.close()을 넣는 것은 멋지게해야합니다.

물론 이것은 vReceivevSend을 호출 할 때마다 클라이언트와 서버가 소켓을 다시 열어야한다는 것을 의미합니다. 그게 바람직하지 않다면, 나는 더 이상 데이터가 전송되지 않을 것이라는 것을 수신자에게 알리는 송신자의 다른 수단을 사용하는 것이 좋습니다.

전선을 통해 전송되는 데이터에 제약이 있는지 여부는 모르겠지만 메시지의 시작 부분에 '데이터 길이'값 또는 일종의 '데이터 끝'센티널 값을 사용하면 더 많은 데이터를 듣지 않아도 될 때를 알기 쉽고 깨끗한 표시가됩니다.

이 접근법은 ASIO의 read_until (또는 이와 유사한) 기능을 사용하여 데이터의 끝을 기다리는 논리를 처리 할 수있는 추가적인 이점을 제공합니다.