Boost ASIO에서 SO_RCVTIMEO 및 SO_SNDTIMEO 소켓 옵션을 설정할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/292997

  •  08-07-2019
  •  | 
  •  

문제

Boost ASIO에서 SO_RCVTIMEO 및 SO_SNDTIMEO 소켓 옵션을 설정할 수 있습니까?

그렇다면 어떻게?

참고 대신 타이머를 사용할 수 있다는 것을 알고 있지만 특히 이러한 소켓 옵션에 대해 알고 싶습니다.

도움이 되었습니까?

해결책

전적으로! BOST ASIO를 사용하면 기본/기본 데이터에 액세스 할 수 있습니다.이 경우 소켓 자체입니다. 그래서 당신이 가지고 있다고 가정 해 봅시다.

boost::asio::ip::tcp::socket my_socket;

그리고 당신이 이미 전화했다고 가정 해 봅시다 open 또는 bind 또는 실제로 만드는 일부 멤버 기능 my_socket 쓸 수 있는. 그런 다음 기본 소켓 값을 얻으려면 다음을 호출하십시오.

SOCKET native_sock = my_socket.native();
int result = SOCKET_ERROR;

if (INVALID_SOCKET != native_sock)
{
    result = setsockopt(native_sock, SOL_SOCKET, <the pertinent params you want to use>);
}

그래서 당신은 그것을 가지고 있습니다! Boost의 Asio를 사용하면 다른 방법보다 더 빨리 많은 일을 할 수 있지만, 여전히 일반 소켓 라이브러리 요구가 필요한 많은 것들이 있습니다. 이것은 그들 중 하나입니다.

다른 팁

Boost.asio (현재 Boost SVN으로)에 내장되지 않은 것처럼 보이지만, 자신의 수업을 기꺼이 작성하여 boost::asio::detail::socket_option 당신은 항상 예제를 따라갈 수 있습니다 boost/asio/socket_base.hpp 다음을 수행하십시오.

typedef boost::asio::detail::socket_option::timeval<SOL_SOCKET, SO_SNDTIMEO>
    send_timeout;
typedef boost::asio::detail::socket_option::timeval<SOL_SOCKET, SO_RCVTIMEO>
    receive_timeout;

(분명히, 나는 당신이 주사 할 것을 제안하지 않습니다 timeval 클래스로 클래스 boost::asio::detail::socket_option 네임 스페이스이지만 현재 사용하기에 좋은 것을 생각할 수 없습니다. :-피)

편집 : 내 샘플 구현 socket_option::timeval, 기준 socket_option::integer:

// Helper template for implementing timeval options.
template <int Level, int Name>
class timeval
{
public:
  // Default constructor.
  timeval()
    : value_(zero_timeval())
  {
  }

  // Construct with a specific option value.
  explicit timeval(::timeval v)
    : value_(v)
  {
  }

  // Set the value of the timeval option.
  timeval& operator=(::timeval v)
  {
    value_ = v;
    return *this;
  }

  // Get the current value of the timeval option.
  ::timeval value() const
  {
    return value_;
  }

  // Get the level of the socket option.
  template <typename Protocol>
  int level(const Protocol&) const
  {
    return Level;
  }

  // Get the name of the socket option.
  template <typename Protocol>
  int name(const Protocol&) const
  {
    return Name;
  }

  // Get the address of the timeval data.
  template <typename Protocol>
  ::timeval* data(const Protocol&)
  {
    return &value_;
  }

  // Get the address of the timeval data.
  template <typename Protocol>
  const ::timeval* data(const Protocol&) const
  {
    return &value_;
  }

  // Get the size of the timeval data.
  template <typename Protocol>
  std::size_t size(const Protocol&) const
  {
    return sizeof(value_);
  }

  // Set the size of the timeval data.
  template <typename Protocol>
  void resize(const Protocol&, std::size_t s)
  {
    if (s != sizeof(value_))
      throw std::length_error("timeval socket option resize");
  }

private:
  static ::timeval zero_timeval()
  {
    ::timeval result = {};
    return result;
  }

  ::timeval value_;
};

이 문제에 대한 쉬운 해결 방법은 기본 읽기 및 쓰기 기능을 사용하는 것입니다.

1 초 타임 아웃으로 작성하려면 :

struct timeval tv = { 1, 0 };
setsockopt(socket.native_handle(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
ssize_t nsent = ::write(socket->native_handle(), buff, size);
if (nsent > 0) {
  BOOST_LOG_TRIVIAL(debug) << "Sent " << nsent << " bytes to remote client " << ep;
} else if (nsent == 0) {
 BOOST_LOG_TRIVIAL(info) <<  "Client " << ep << " closed connection";
} else if (errno != EAGAIN) {
  BOOST_LOG_TRIVIAL(info) <<  "Client " << ep << " error: " <<     strerror(errno);
}

1 초 타임 아웃으로 읽기 :

struct timeval tv = { 1, 0 };
setsockopt(socket.native_handle(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
ssize_t nread = ::read(socket.native_handle(), buff, audio_buff_size);
if (nread > 0) {
} else if (nread == 0) {
  BOOST_LOG_TRIVIAL(info) <<  "Source " << source << " server " << host << " closed connection";
  break;
} else if (errno != EAGAIN) {
  BOOST_LOG_TRIVIAL(info) <<  "Source " << source << " server " << host << " error: " << strerror(errno);
  break;
}

이것은 나를 위해 잘 작동했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top