我有一个提升异步tcp客户端,它需要始终从服务器接收数据。 我想把那个时间放在那里,当没有数据在n秒内与服务器断开连接并尝试连接时。 我使用vc ++。
void tcpclient::Connect(){
.....
socket_.async_connect(*iterator,boost::bind(&tcpclient::AfterConnection,shared_from_this(),boost::asio::placeholders::error));
}
void tcpclient::AfterConnection(const boost::system::error_code& error){
if (!error)
{
SetTimeout();
}
}
void tcpclient::SetTimeout(int sec = 1)
{
SOCKET native_sock = socket_.native();
int result = SOCKET_ERROR;
if (INVALID_SOCKET != native_sock)
{
struct timeval tv;
tv.tv_sec = sec;
tv.tv_usec = 0;
result = setsockopt(native_sock, SOL_SOCKET, SO_RCVTIMEO,(char *)&tv,sizeof(struct timeval));
i = GetLastError();
}
}
我看起来像打击:
socket_.async_receive(boost::asio::buffer(buffer, 1024),
boost::bind(&tcpClient::handleReceive,
shared_from_this(),
boost::asio::placeholders::error,
buffer,
boost::asio::placeholders::bytes_transferred)
);
但是,当我尝试模拟不能保持数据连接的情况时,请保持原状:
$ netstat -ao
TCP 192.168.0.6:62836 192.168.0.5:telnet ESTABLISHED 2840
发生这种情况的原因是什么?
答案 0 :(得分:1)
设置SO_RCVTIMEO
会导致对read
的其他阻塞调用在等待指定时间后没有数据返回,因为非阻塞套接字会立即执行。
所以,问题是,当read
返回EWOULDBLOCK错误时,你或Boost做了什么?你需要展示你是如何阅读的;如果Boost在事件循环中处理它(基于select
或poll
),它可能只是等待一些数据可用。
如果是这种情况,更好的方法是使用事件循环注册一个计时器回调来每秒或多次触发,并检查在前一秒内是否收到了一些数据。套接字选项对你没有帮助。