我一直在使用同一网站上发布的以下example。这是我的版本。 (请原谅我缺乏C套接字编程的经验:)
在构造函数中:
server::server(io_service& io_service, const int port) :
udpsocket_(io_service, udp::endpoint(udp::v4(), port))) {
int sock = udpsocket_.native();
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
int opt = 1;
setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt));
}
其中“udpsocket_”实际上是一个提升asio udp套接字。这非常方便,因为一方面我可以使用一个函数从传入的UDP消息中获取目标IP,而无需使用原始套接字:
void get_destination_IP() {
int sock = udpsocket_.native();
char cmbuf[0x100];
struct sockaddr_in peeraddr;
struct msghdr mh;
mh.msg_name = &peeraddr;
mh.msg_namelen = sizeof(peeraddr);
mh.msg_control = cmbuf;
mh.msg_controllen = sizeof(cmbuf);
int received = recvmsg(sock, &mh, 0);
for ( // iterate through all the control headers
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);
cmsg != NULL;
cmsg = CMSG_NXTHDR(&mh, cmsg))
{
if (cmsg->cmsg_level != IPPROTO_IP ||
cmsg->cmsg_type != IP_PKTINFO)
{
continue;
}
struct in_pktinfo *pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
char* destAddr = (char*) calloc(4, sizeof(char));
destAddr = inet_ntoa(pi->ipi_spec_dst);
stored_UDP_dest_ip_ = ip::address::from_string(destAddr);
}
}
现在问题出现了:
如:
udpsocket_.async_receive_from(
boost::asio::buffer(msg_),
udp_endpoint_,
boost::bind(&server::UDP_recv_handler,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
handler
)
);
函数“recvmsg”存储正确的目标IP信息,但返回0.理论上,根据手册页,返回“size_t numbytes”。我还能用“recvmsg”读取数据报吗?
构造函数中是否需要FD_ZERO?
每次调用“get_destination_IP”时都需要FD_ZERO吗?
先感谢您的帮助
答案 0 :(得分:0)
请参阅boost:asio :: null_buffers()功能。如果你将boost :: asio :: null_buffers()传递给boost :: asio async _ *()函数,那么当数据可用时调用处理程序,你可以(需要)自己接收它(例如,通过recvmsg()在你的情况下)。
fdset未使用且无用。套接字池是由boost :: asio为你完成的。