我尝试使用 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
但是,该代码不起作用。 如果您有任何示例代码或解决方案,请告诉我。 谢谢你。
起点是一个处理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;