C++ 您能在boost asio中设置SO_RCVTIMEO和SO_SNDTIMEO插槽选项吗?

C++ 您能在boost asio中设置SO_RCVTIMEO和SO_SNDTIMEO插槽选项吗?,c++,boost,boost-asio,C++,Boost,Boost Asio,您能在boost asio中设置SO_RCVTIMEO和SO_SNDTIMEO插槽选项吗 如果是,怎么做 注:我知道您可以使用定时器,但我想特别了解这些插座选项 它似乎没有内置到Boost.Asio中(从当前的Boost SVN开始),但是,如果您愿意编写自己的类来模拟Boost::Asio::detail::socket_选项的话,您可以始终遵循Boost/Asio/socket_base.hpp中的示例并执行以下操作: typedef boost::asio::detail::socket_

您能在boost asio中设置SO_RCVTIMEO和SO_SNDTIMEO插槽选项吗

如果是,怎么做


注:我知道您可以使用定时器,但我想特别了解这些插座选项

它似乎没有内置到Boost.Asio中(从当前的Boost SVN开始),但是,如果您愿意编写自己的类来模拟
Boost::Asio::detail::socket_选项
的话,您可以始终遵循
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允许您访问本机/底层数据,在本例中是套接字本身。那么,假设你有:

boost::asio::ip::tcp::socket my_socket;
假设您已经调用了
open
bind
或某个成员函数,该函数实际上使
myu 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>);
}
SOCKET native_sock=my_SOCKET.native();
int结果=套接字错误;
if(无效的\u套接字!=本机\u套接字)
{
结果=setsockopt(本机插槽、SOL插槽);
}

好了,给你!Boost的ASIO可以让您以比其他方式更快的速度完成许多事情,但仍有许多事情需要正常的套接字库调用。这恰好是其中之一。

解决此问题的一个简单方法是使用本机读写函数

对于使用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);
}
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;
}
struct timeval tv={1,0};
setsockopt(socket.native_handle(),SOL_socket,SO_SNDTIMEO,&tv,sizeof(tv));
ssize\u t nsent=::write(套接字->本机句柄(),buff,size);
如果(nsent>0){

BOOST\u LOG\u琐碎(调试)我不能只做:typedef boost::asio::detail::socket_option::integer send_timeout;和recv timeout一样吗?为什么你也需要timeval结构?哈哈哈,你会在我的答案的第一个版本中看到,这也是我的想法。但是,阅读后,你会看到超时值使用timeval,而不是int。注意:在Win32上,采用
DWORD
,而不是
timeval
。除最低级别的send/recv函数外,所有函数都在显式捕获EAGAIN的调用周围具有for(;)循环。这有效地使SO{SND,RCV}TIMEO选项毫无用处,除非您在Boost中丢弃95%的发送/接收函数。因此,它们允许您设置选项是毫无意义的,因为利用它的唯一方法是不使用库的其余部分…为什么?asio读/写有什么问题?
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;
}