2016-10-19 1 views
2

도메인 소켓을 청취하기로되어있는 클라이언트를 작성하고 있습니다. 동기 연결을 열고 동기 쓰기를하고 소켓에 eavesdrop에 socat을 사용하고 있기 때문에 서버가 유효한 응답을 보내는 것을 알고 있습니다.Asio가 원격 시스템의 응답을 수신하지 않습니다.

asio::read()이 호출되었지만 결코 데이터를 반환하지 않는 것을 제외하고. 내가 건네주는 버퍼는 항상 비어 있습니다. 여기 내 코드입니다 :

void operator>>(const vector<unsigned char> input, Socket &socket) { 
     const size_t size = input.size(); 
     const size_t bytes = asio::write(socket.connection_socket, asio::buffer(input, size)); 
     if (bytes != size) { 
     const std::error_code ec; 
     throw std::system_error(ec, fmt::format("Tried to send {0} bytes but sent {1} instead.", size, bytes)); 
     } 
     string buffer; 
     asio::read(socket.connection_socket, asio::buffer(buffer)); 
     std::cerr << buffer << std::endl; 
    } 

이 내가 소켓에 연결하는 데 사용하는 속성입니다 :

io_service run_loop; 
stream_protocol::socket connection_socket; 
datagram_protocol::endpoint domain_socket_ep; 

Socket 운영자 과부하가 위의 선언 모든하는 Asio 코드를 래핑하는 간단한 클래스는 .

답변

1

asio::read의 기능은 이고 많게는asio::buffer_size(asio::buffer(buffer)) 바이트입니다. 당신의 경우 buffer이 비어 있으므로 대부분 0 바이트로 읽습니다.

Asio는 전달할 버퍼의 크기를 절대로 변경하지 않으므로 buffer의 크기를 원하는 최대 크기로 조정해야합니다.

또한, asio::read 함수는 실제로 입력 버퍼의 크기보다 작은 바이트를 읽을 수 있습니다. 읽은 실제 크기는 해당 함수에서 반환됩니다. 따라서 버퍼에 들어갈 수있는 바이트 수를 정확하게 읽고 쓰려면 다음과 같이해야합니다.

void read_to_buffer(asio::ip::tcp::socket& s, asio::buffer buffer) { 
    size_t read = 0; 
    size_t n = asio::buffer_size(buffer); 
    while (read < n) { 
     read += asio::read(s, buffer + read)); 
    } 
} 

void write_from_buffer(asio::ip::tcp::socket& s, asio::buffer buffer) { 
    size_t written = 0; 
    size_t n = asio::buffer_size(buffer); 
    while (written < n) { 
     written += asio::write(s, buffer + written)); 
    } 
} 

void operator>>(const vector<unsigned char> input, Socket &socket) { 
     // TODO: convert between host and network byte order 
     auto& s = socket.connection_socket; 
     { 
     const uint32_t size = input.size(); 
     write_from_buffer(s, asio::buffer(&size, sizeof(size)); 
     write_from_buffer(s, asio::buffer(input)); 
     } 
     { 
     uint32_t size = 0; 
     read_to_buffer(s, asio::buffer(&size, sizeof(size))); 
     string payload(size, 'x'); 
     read_to_buffer(s, asio::buffer(payload)); 
     std::cerr << payload << std::endl; 
     } 
} 
+0

잘 모르겠습니다. 소켓에 쓰는 것은 괜찮습니다. asio는 그냥 읽지 않습니다. 왜 두 번 쓰고 읽어야합니까? 또한 asio :: read_some과 동일한 작업을 수행하는 read_to_buffer()가 아닌가? – ruipacheco

+0

크기가 0 인 문자열을 asio :: read 함수에 전달하여 "_asio는 단지 it_에서 읽지 않습니다."라고하면 asio에 0 바이트를 읽게됩니다. TCP 소켓은 보낸 바이트 수를 알지 못합니다. "_ asio :: read_some_과 동일합니다."죄송합니다. [API] (http://www.boost.org/doc/libs/1_62_0/doc/html/)에 나열된'asio :: read_some' 함수가 표시되지 않습니다. boost_asio/reference.html), 어느 것을 의미합니까? –

+0

나는 socket.read_some()을 의미했습니다. http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/basic_stream_socket/read_some/overload1.html – ruipacheco

관련 문제