我想用boost asio写个udp的服务器,功能是监听客户端的连接,连接后就保存该客户端信息,之后通过其他线程向所有客户端循环发送消息。 现在已经写好了,并且能成功发送消息。但是当客户端关闭后,出现了两个问题。
1、循环往已经关闭的客户端发送消息,在客户端关闭后还是可以发送成功。
2、客户端关闭后(没有新连接),监听回调开始不断地调用
这两个问题出在哪里,有没有人解释一下。谢谢,下面是大概的代码
ip::udp::endpoint remote_endpoint_[16];
void CFullScan::handle_receive(const boost::system::error_code& error, std::size_t /*bytes_transferred*/)
{
// 一个监听到后开始监听下一个客户端。
g_remoteNum = 16;
int i;
for (i = 0; i < MAX_UPD_SOCKET; i++) {
if (remote_endpoint_[i].port() == 0) {
break;
}
}
StartAccept(i);
}
void CFullScan::handle_send(const boost::system::error_code& error, std::size_t /*bytes_transferred*/, int index)
{
cout << error << endl;
// 客户端断开后这里的发送结果还是success,不知道问题在哪
if (!error) {
cout << "success" << ":" << index << "-ip"<< remote_endpoint_[index].address()<< ":" <<remote_endpoint_[index].port() <<endl;
} else {
cout << "failed" << endl;
remote_endpoint_[index].port(0);
}
}
void CFullScan::StartAccept(int remoteNum)
{
boost::array<char, 1> recv_buffer_;
cout << "wait receive = " << remoteNum << endl;
if (remoteNum != 0) {
cout << remoteNum << ":" << remote_endpoint_[remoteNum - 1].address() << ":" << remote_endpoint_[remoteNum - 1].port() << endl;
}
// 启动监听客户端,udp协议所以只需要等待客户端发消息。(问题就是这里,当客户端断开后,这个监听一直可以触发回调就很奇怪。)
udpSocket.async_receive_from(boost::asio::buffer(recv_buffer_), remote_endpoint_[remoteNum],
boost::bind(&CFullScan::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
//StartAcceptEx(&(*udpIt));
}
// 发送函数在另一个定时器触发,循环触发。handle_send就是发送结果回调
void CFullScan::startToSendMessage(string str, int length)
{
for (int i = 0; i < MAX_UPD_SOCKET - 1; i++) {
if (remote_endpoint_[i].port() == 0) {
continue;
}
for (int j = i + 1; j <MAX_UPD_SOCKET; j++) {
if (remote_endpoint_[i].address() == remote_endpoint_[j].address() && remote_endpoint_[i].port() == remote_endpoint_[j].port()) {
remote_endpoint_[i].port(0);
break;
}
}
}
char newBuff[2048] = {0};
int len = str.length() > 2047 ? 2047 : str.length();
str.copy(newBuff, len, 0);
newBuff[2047] = '\0';
//printf("string = %s\n", newBuff);
for (int i = 0; i < MAX_UPD_SOCKET; i++) {
if (remote_endpoint_[i].port() == 0) {
continue;
}
char buff[32] = "The message from server\n";
udpSocket.async_send_to(boost::asio::buffer(newBuff), remote_endpoint_[i],
boost::bind(&CFullScan::handle_send, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, i));
}
}