boost :: asio :: read () 블록을 영원히

엠레 데스

Boost.asio가 어떻게 작동하는지 배우려고합니다. 다음과 같은 기본 서버 및 클라이언트 예제를 작성했습니다.

server.cpp

#include <iostream>
#include <string>
#include <boost/asio.hpp>

#define PORT 27015

using namespace boost::asio;
using ip::tcp;

std::string read(tcp::socket& socket) {
    boost::system::error_code error;
    boost::asio::streambuf buffer;
    boost::asio::read(socket, buffer, boost::asio::transfer_all(), error);
    if (error) {
        std::cerr << "read error: " << error.message() << "\n";
        return "ERROR";
    }
    else {
        std::string data = boost::asio::buffer_cast<const char*>(buffer.data());
        return data;
    }
}

void send(tcp::socket& socket, const std::string& message) {
    boost::system::error_code error;
    boost::asio::write(socket, boost::asio::buffer(message), error);
    if (error)
        std::cerr << "send error: " << error.message() << "\n";
    else
        std::cout << "sent \"" << message << "\" to the client" << "\n";
}

int main() {
    boost::asio::io_service io_service;

    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), PORT)); // create listener for new connection(s)
    tcp::socket socket(io_service); // socket creation

    std::cout << "awaiting connection..." << "\n";
    acceptor.accept(socket); // direct connection(s) to the socket we created
    std::cout << "accepted connection!" << "\n";

    std::string received = read(socket); // receive data
    std::cout << "received message: " << received << "\n";

    send(socket, "hello from server!"); // send data
}

client.cpp

#include <iostream>
#include <string>
#include <boost/asio.hpp>

#define PORT 27015

using namespace boost::asio;
using ip::tcp;

int main(int argc, char *argv[])
{
    boost::asio::io_service io_service;
    tcp::socket socket(io_service); // socket creation

    std::string server_ipv4_address = "192.168.1.2";
    std::cout << "connecting to server at " << server_ipv4_address << "\n";

    try {
        socket.connect(tcp::endpoint(boost::asio::ip::address::from_string(server_ipv4_address), PORT)); // connection
        std::cout << "connected!" << "\n";
    }
    catch (const boost::system::system_error& e) {
        std::cerr << "error while connecting: " << e.what() << "\n";
        return -1;
    }

    boost::system::error_code error; // error holder

    std::string message = "hello from client!!\n";
    boost::asio::write(socket, boost::asio::buffer(message), error); // send message to server
    if (error)
        std::cerr << "send failed: " << error.message() << "\n";
    else
        std::cout << "sent \"" << message << "\" to the server" << "\n";

    boost::asio::streambuf receive_buffer;
    boost::asio::read(socket, receive_buffer, boost::asio::transfer_all(), error); // receive from server
    if (error && error != boost::asio::error::eof)
        std::cerr << "receive failed: " << error.message() << "\n";
    else {
        std::string data = boost::asio::buffer_cast<const char*>(receive_buffer.data());
        std::cout << "received data: " << data << "\n";
    }
}

연결이 제대로 설정되지만 서버의 read () 함수는 클라이언트로부터 데이터를받지 못하거나 호출 방식에 문제가 있기 때문에 프로그램을 차단합니다. boost::asio::read()여기에 문제가있는 것 같 습니까? 내가 바꿀 경우 모든 것이 제대로 작동 boost::asio::read과 함께 boost::asio::read_until아래 그림과 같이. 기능이 클라이언트에서는 제대로 작동하지만 서버에서는 작동하지 않는 이유는 무엇입니까?

std::string read(tcp::socket& socket) {
    boost::system::error_code error;
    boost::asio::streambuf buffer;
    boost::asio::read_until(socket, buffer, "\n");
    std::string data = boost::asio::buffer_cast<const char*>(buffer.data());
    return data;
}
보다

완료 조건으로 transfer_all읽기는 버퍼가 가득 차거나 연결이 무효화 될 때까지 계속 읽기를 의미합니다.

버퍼는 "절대"가득 차지 않습니다 (DynamicBuffer이기 때문에).

따라서 클라이언트가 끊지 않는 원인이 남습니다.

아래와 같이 boost :: asio :: read를 boost :: asio :: read_until로 바꾸면 모든 것이 제대로 작동합니다.

바로 그거죠. 그렇다면 독서를 중단해야 할 또 다른 이유가 있기 때문입니다. 당신을 명심하십시오, 그것은 여전히 ​​영원히 막을 수 있습니다 ( '\n'도착하지 않을 ).

기능이 클라이언트에서는 제대로 작동하지만 서버에서는 작동하지 않는 이유는 무엇입니까?

그렇지 않습니다. 서버가 연결을 종료 (신호 EOF)하기 때문인 것 같습니다. [이후 읽기가 error_code boost :: asio :: error :: eof를 반환하기 때문에 이것을 알 수 있습니다.]

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

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

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Boost :: Asio-read 또는 read_until?

분류에서Dev

boost :: asio :: read는 boost : asio :: write가 Java 소켓으로 데이터를 보내는 것을 방지합니다.

분류에서Dev

"2 단계"async_read with boost asio

분류에서Dev

"2 단계"async_read with boost asio

분류에서Dev

Boost.Asio : socket :: close가 aysnc_read_some을 취소하지 않음

분류에서Dev

Create timer with boost::asio

분류에서Dev

boost :: asio는 로컬 메모리 내 연결을 지원합니까?

분류에서Dev

boost :: asio asyn_read with timer가 좋은 생각입니까?

분류에서Dev

boost :: asio :: read를 사용하여 cout에 직접 쓰기

분류에서Dev

Boost.Asio TCP가 소켓 소멸자로 이동하여 완전히 닫을 수 없습니까?

분류에서Dev

boost :: asio :: spawn yield as callback

분류에서Dev

boost :: asio :: async_read_some에 전달 된 콜백은 boost :: asio :: read_some이 데이터를 반환하는 사용시 호출되지 않았습니다.

분류에서Dev

boost :: asio :: async_read_some에 전달 된 콜백은 boost :: asio :: read_some이 데이터를 반환하는 사용시 호출되지 않았습니다.

분류에서Dev

boost :: asio :: async_read 줄 바꿈에서 파일 끝 오류 반환

분류에서Dev

Arduino와 C ++ Boost :: asio 직렬 통신을 쓸 수 없습니다.

분류에서Dev

CMake가 boost_asio를 찾을 수 없습니다.

분류에서Dev

boost :: asio의 Valgrind 오류

분류에서Dev

Taking the port from Boost Asio socket

분류에서Dev

`boost :: asio :: streambuf`에서 파생

분류에서Dev

블록 체인 데이터는 영원히 저장됩니까?

분류에서Dev

C ++ Boost Asio-연결 끊김을 감지하고 모든 활성 연결 목록을 만드는 방법

분류에서Dev

boost :: asio :: spawn을 위해 io_context를 언제 전달해야합니까? (C ++)

분류에서Dev

boost.asio에서 요청을 어떻게 인쇄 할 수 있습니까?

분류에서Dev

boost :: asio ioservice는 나머지 코드 실행을 유지합니다.

분류에서Dev

Boost없이 Xcode C ++ 11에서 Asio 독립형을 사용하는 방법

분류에서Dev

"C ++ boost :: asio 재귀 타이머 콜백"이 콜 스택을 누적합니까?

분류에서Dev

boost :: serialization을 통해 여러 std :: shared_ptr 직렬화 및 boost :: asio를 통해 전송

분류에서Dev

Boost blocking read timeout

분류에서Dev

목록의 항목을 영원히 실행하는 방법-Python

Related 관련 기사

  1. 1

    Boost :: Asio-read 또는 read_until?

  2. 2

    boost :: asio :: read는 boost : asio :: write가 Java 소켓으로 데이터를 보내는 것을 방지합니다.

  3. 3

    "2 단계"async_read with boost asio

  4. 4

    "2 단계"async_read with boost asio

  5. 5

    Boost.Asio : socket :: close가 aysnc_read_some을 취소하지 않음

  6. 6

    Create timer with boost::asio

  7. 7

    boost :: asio는 로컬 메모리 내 연결을 지원합니까?

  8. 8

    boost :: asio asyn_read with timer가 좋은 생각입니까?

  9. 9

    boost :: asio :: read를 사용하여 cout에 직접 쓰기

  10. 10

    Boost.Asio TCP가 소켓 소멸자로 이동하여 완전히 닫을 수 없습니까?

  11. 11

    boost :: asio :: spawn yield as callback

  12. 12

    boost :: asio :: async_read_some에 전달 된 콜백은 boost :: asio :: read_some이 데이터를 반환하는 사용시 호출되지 않았습니다.

  13. 13

    boost :: asio :: async_read_some에 전달 된 콜백은 boost :: asio :: read_some이 데이터를 반환하는 사용시 호출되지 않았습니다.

  14. 14

    boost :: asio :: async_read 줄 바꿈에서 파일 끝 오류 반환

  15. 15

    Arduino와 C ++ Boost :: asio 직렬 통신을 쓸 수 없습니다.

  16. 16

    CMake가 boost_asio를 찾을 수 없습니다.

  17. 17

    boost :: asio의 Valgrind 오류

  18. 18

    Taking the port from Boost Asio socket

  19. 19

    `boost :: asio :: streambuf`에서 파생

  20. 20

    블록 체인 데이터는 영원히 저장됩니까?

  21. 21

    C ++ Boost Asio-연결 끊김을 감지하고 모든 활성 연결 목록을 만드는 방법

  22. 22

    boost :: asio :: spawn을 위해 io_context를 언제 전달해야합니까? (C ++)

  23. 23

    boost.asio에서 요청을 어떻게 인쇄 할 수 있습니까?

  24. 24

    boost :: asio ioservice는 나머지 코드 실행을 유지합니다.

  25. 25

    Boost없이 Xcode C ++ 11에서 Asio 독립형을 사용하는 방법

  26. 26

    "C ++ boost :: asio 재귀 타이머 콜백"이 콜 스택을 누적합니까?

  27. 27

    boost :: serialization을 통해 여러 std :: shared_ptr 직렬화 및 boost :: asio를 통해 전송

  28. 28

    Boost blocking read timeout

  29. 29

    목록의 항목을 영원히 실행하는 방법-Python

뜨겁다태그

보관