你可以在boost asio中设置SO_RCVTIMEO和SO_SNDTIMEO套接字选项吗?你可以在boost asio中设置SO_RCVTIMEO和SO_SNDTIMEO套接字选项吗?
如果是这样怎么样?
注意我知道你可以使用计时器,但我想特别了解这些套接字选项。
你可以在boost asio中设置SO_RCVTIMEO和SO_SNDTIMEO套接字选项吗?你可以在boost asio中设置SO_RCVTIMEO和SO_SNDTIMEO套接字选项吗?
如果是这样怎么样?
注意我知道你可以使用计时器,但我想特别了解这些套接字选项。
绝对! Boost ASIO允许您访问本机/底层数据,在本例中是SOCKET本身。所以,让我们说你有:
boost::asio::ip::tcp::socket my_socket;
而且让我们说你已经叫open
或bind
或某些成员函数,实际上使my_socket
使用。然后,要获得底层的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的(如电流升压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
命名空间,但我想不出一个好目前使用的:-P)。
编辑:我的示例实现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;
}
这对我工作的罚款。
难道我不能这样做: typedef boost :: asio :: detail :: socket_option :: integer send_timeout; 和recv超时一样吗?为什么你还需要timeval结构? –
2008-11-20 00:29:12
哈哈哈,你会在我的答案的第一个版本中看到,这也是我的想法。但是,请阅读http://www.opengroup.org/onlinepubs/009695399/functions/setsockopt.html,您将看到超时值使用timeval而不是int。 – 2008-11-20 04:43:49