부스트 ASIO에서 SO_RCVTIMEO 및 SO_SNDTIMEO 소켓 옵션을 설정할 수 있습니까?부스트 asio에서 SO_RCVTIMEO 및 SO_SNDTIMEO 소켓 옵션을 설정할 수 있습니까?
그렇다면 어떻게됩니까?
참고 타이머를 대신 사용할 수 있지만이 소켓 옵션에 대해 알고 싶습니다.
부스트 ASIO에서 SO_RCVTIMEO 및 SO_SNDTIMEO 소켓 옵션을 설정할 수 있습니까?부스트 asio에서 SO_RCVTIMEO 및 SO_SNDTIMEO 소켓 옵션을 설정할 수 있습니까?
그렇다면 어떻게됩니까?
참고 타이머를 대신 사용할 수 있지만이 소켓 옵션에 대해 알고 싶습니다.
물론입니다! Boost ASIO를 사용하면 기본/기본 데이터 (이 경우 SOCKET 자체)에 액세스 할 수 있습니다.
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;
(물론, 난 당신이 boost::asio::detail::socket_option
네임 스페이스에 timeval
클래스를 주입 제안 아니지만, 나는 순간에 사용하는 것이 하나 생각할 수 없다 - P.) 그리고 다음을 수행
편집 : 내 샘플 구현 socket_option::timeval
,기준:
// 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_;
};
그냥 할 수 없어 : typedef boost :: asio :: detail :: socket_option :: integer
하하하, 내 대답의 첫 번째 버전에서 보게 될 것입니다. 그것이 내가 생각한 것입니다. 그러나 http://www.opengroup.org/onlinepubs/009695399/functions/setsockopt.html을 읽고 타임 아웃 값은 int가 아니라 timeval을 사용하는 것을 볼 수 있습니다. –
이 문제의 쉬운 해결 방법은 기본 읽기 및 쓰기 기능을 사용하는 것입니다. 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;
}
이 나를 위해 잘 일했다.
가장 낮은 레벨의 send/recv 기능을 제외하고 모두 EAGAIN을 명시 적으로 catch하는 호출에 대해 (;;) 루프가 있습니다. Boost에서 송수신 기능의 95 %를 폐기하지 않으면 SO_ {SND, RCV} TIMEO 옵션이 효과적으로 쓸모 없게됩니다. 따라서 옵션을 설정하는 것이 허용된다는 것은 의의가 있습니다. 라이브러리의 나머지 부분을 사용하지 않는 것이 유일한 방법이기 때문에 ... – Tom
우수 포인트. 나는 지금 이것을 치렀다. 젠장. –