获取UDP数据包的目的地址

获取UDP数据包的目的地址

本文介绍了获取UDP数据包的目的地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用同一网站上发布的以下示例.这是我的版本.(请原谅我缺乏 C 套接字编程经验:)

I have been using the following example posted in this same site. This is my version of it. (Please excuse my lack of experience with C socket programming:)

在构造函数中:

    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_"实际上是一个 boost asio udp 套接字.这非常方便,因为一方面我可以有一个函数从传入的 UDP 消息中获取目标 IP,而无需使用原始套接字:

Where "udpsocket_" is actually a boost asio udp socket. This is very convenient since on one hand I can have a function which gets the destination IP from the incoming UDP message without the need for using a raw socket:

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);
    }
}

问题来了:

  • 我能否像调用async_receive_from"一样以非阻塞方式异步调用此get_destination_IP"?

如:

  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"读取数据报吗?

    • Function "recvmsg" stores the right destination IP info, but returns 0. In theory according to the man page, the "size_t numbytes" is returned there. Can I still read the datagram with "recvmsg"?

      在构造函数中是否需要 FD_ZERO?

      Is FD_ZERO necessary in the constructor?

      每次调用get_destination_IP"时都需要 FD_ZERO 吗?

      Is FD_ZERO necessary at every call of "get_destination_IP"?

      在此先感谢您的帮助

      推荐答案

      参见 boost:asio::null_buffers() 功能.如果您将 boost::asio::null_buffers() 传递给 boost::asio async_*() 函数,则在数据刚好可用时调用处理程序,您可以(需要)自己接收它(例如,通过 recvmsg()在你的情况下).

      See boost:asio::null_buffers() feature. If you pass boost::asio::null_buffers() to boost::asio async_*() functions then the handler is invoked when data is just available and you can (need to) receive it by yourself (eg, by recvmsg() in your case).

      fdset 在那里未使用且无用.套接字池由 boost::asio 为您完成.

      fdset is unused and useless there. Socket pooling is done by boost::asio for you.

      这篇关于获取UDP数据包的目的地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 21:47