如何使用自定义命令io_control boost库套接字

问题描述 投票:0回答:1

我尝试使用 boost 库以 C++ 风格制作与“ioctl”相同的函数。

这是我的“c”风格代码:

int sockfd;
char * id;
struct iwreq wreq;

memset(&wreq, 0, sizeof(struct iwreq));
sprintf(wreq.ifr_name, IW_INTERFACE);

if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    fprintf(stderr, "Cannot open socket \n");
    fprintf(stderr, "errno = %d \n", errno);
    fprintf(stderr, "Error description is : %s\n",strerror(errno));
    exit(1);
}
printf("Socket opened successfully \n");


id = malloc(IW_ESSID_MAX_SIZE+1);
wreq.u.essid.pointer = id;
if (ioctl(sockfd, SIOCGIWESSID, &wreq)) {
    fprintf(stderr, "Get ESSID ioctl failed \n");
    fprintf(stderr, "errno = %d \n", errno);
    fprintf(stderr, "Error description : %s\n",strerror(errno));
    exit(2);
}
printf("IOCTL Successfull\n");
printf("ESSID is %s\n", wreq.u.essid.pointer);

我找到了一些相关的例子,但我不清楚如何正确使用它。 示例

主要功能:

boost::asio::ip::udp::socket socket(io_service);
struct iwreq wreq
memset(&wreq, 0, sizeof(struct iwreq));
sprintf(wreq.ifr_name, IW_INTERFACE);
id = malloc(IW_ESSID_MAX_SIZE+1);
wreq.u.essid.pointer = id;

boost::asio::detail::io_control::myCommand command;
command.set(&wreq);
boost::system::error_code ec;
socket.io_control(command, ec);
if (ec)
{
  // An error occurred.
}

自定义命令:

#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/config.hpp>
#include <boost/asio/detail/socket_types.hpp>

#include <boost/asio/detail/push_options.hpp>

namespace boost {
namespace asio {
namespace detail {
namespace io_control {

// I/O control command for getting number of bytes available.
class myCommand
{
public:
  // Default constructor.
  myCommand()
    : value_(0)
  {
  }


  // Get the name of the IO control command.
  int name() const
  {
    return static_cast<int>(SIOCGIWESSID);
  }

  // Set the value of the I/O control command.
  void set(struct iwreq* value)
  {
    value_ = static_cast<detail::ioctl_arg_type>(value);
  }

  // Get the current value of the I/O control command.
  std::size_t get() const
  {
    return static_cast<struct iwreq*>(value_);
  }

  // Get the address of the command data.
  detail::ioctl_arg_type* data()
  {
    return &value_;
  }

  // Get the address of the command data.
  const detail::ioctl_arg_type* data() const
  {
    return &value_;
  }

private:
  detail::ioctl_arg_type value_;
};

} // namespace io_control
} // namespace detail
} // namespace asio
} // namespace boost

但是,该代码不起作用。 如果您有任何示例代码或解决方案,请告诉我。 谢谢你。

boost-asio ioctl
1个回答
0
投票

起点是一个处理ioctl命令

FIONREAD
的Asio类。该命令的参数是一个指向整数的指针(它将存储输出)。它的 C 风格代码可能如下所示:

int fd, ret;
int value; // NOTE: type is platform-specific

/* ... */

ret = ioctl(fd, FIONREAD, &value);

在Asio类

bytes_readable
中,该整数就是成员变量
value_
。当此类的实例传递给
basic_socket::io_control()
时,它将被设置。

对于 ioctl 命令

SIOCGIWESSID
,参数是指向
struct iwreq
的指针。因此,在自定义 Asio 类中,更改
value_
的类型以匹配:

#include <linux/wireless.h>

class MyCommand
{
public:
  /* ... */

  // Get the name of the IO control command.
  int name() const
  {
    return static_cast<int>(SIOCGIWESSID);
  }

  // Get the address of the command data.
  struct iwreq* data()
  {
    return &value_;
  }

  // Get the address of the command data.
  const struct iwreq* data() const
  {
    return &value_;
  }

private:
  struct iwreq value_;
};

然后添加构造函数、访问器和/或修改器,以获取或设置

struct iwreq
的各个字段。

根据实现的不同,该类可能会这样使用:

boost::asio::ip::udp::socket socket(io_service);

MyCommand cmd(IW_INTERFACE);

boost::system::error_code ec;
socket.io_control(cmd, ec);
if (ec)
{
  // An error occurred.
}

std::string essid = cmd.essid();
std::cout << "ESSID is " << essid << std::endl;
© www.soinside.com 2019 - 2024. All rights reserved.