2008-11-15 152 views

回答

3

绝对! Boost ASIO允许您访问本机/底层数据,在本例中是SOCKET本身。所以,让我们说你有:

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

而且让我们说你已经叫openbind或某些成员函数,实际上使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可以让你更快地完成许多事情,否则你仍然需要很多正常的套接字库调用。这恰好是其中之一。

3

它似乎并没有被内置到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_; 
}; 
+0

难道我不能这样做: typedef boost :: asio :: detail :: socket_option :: integer send_timeout; 和recv超时一样吗?为什么你还需要timeval结构? – 2008-11-20 00:29:12

+0

哈哈哈,你会在我的答案的第一个版本中看到,这也是我的想法。但是,请阅读http://www.opengroup.org/onlinepubs/009695399/functions/setsockopt.html,您将看到超时值使用timeval而不是int。 – 2008-11-20 04:43:49

0

解决此问题的一个简单方法是使用本机读取和写入功能。

对于具有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; 
} 

这对我工作的罚款。

相关问题