使用boost asio在C 中发送layer2
Using boost asio to send layer2 in C++
当前的gnuradio udp sind/源块使用UDP将数据包发送/从NIC发送/输出。它使用Boost ASIO进行发送/接收。我需要修改这些UDP接收器/源块,以使用IP处理两个UDP,以使现有功能可以越过1GB NIC并添加Boost Raw套接字/协议,以便我们可以在没有IP上的IP上发送layer2 packept没有IP地址(接收器是一个FPGA,具有自定义错误检查/恢复等)。
仅使用C,我有测试程序,可以根据需要制作数据包并将其发送出去并在另一侧接收。他们来自:
使用Boost ASIO RAW插座创建一个2层/以太网套接字(在C 中)http://qiita.com/kadopoly/items/acafa01945e5cfe39270
由于Gnuradio在C 中,我需要修改Boost套接字/协议设置以适合UDP_SINK_IMPL.CC和UDP_SINK_IMPL.H.H文件,以便我可以发送数据包。
。堆栈溢出链接似乎是最直接的(我不是经验丰富的编码器),我能够将其添加到我的gnuradio块中并传输。它不会正确发送TransMitBuffer2缓冲区(发送了一个数据包,但内容错误),但确实发送了Hello World!溪流缓冲区正确,这对我来说是未知的。但是它无法处理0x00,所以我无法使用它来测试发送的MAC地址。
这是我目前拥有的:
udp_sink_impl.h代码:
char tmpHeaderBuff[12]; // 32-bit sync word (0xFFFFFFFF), 32-bit sequence num and 32-bit data size
unsigned char custom_type[2] = {0x82,0x00};
unsigned char ethHeader[12] = {0x00,0x0c,0x29,0x05,0x0d,0x15,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char mac_str[6];
unsigned char dstMAC[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char srcMAC[6];
/* 1G management stuff */
boost::asio::io_service d_io_service;
boost::asio::ip::udp::endpoint d_endpoint;
boost::asio::ip::udp::socket *udpsocket;
/* 1G management stuff */
/* 10G raw socket stuff */
typedef boost::asio::generic::raw_protocol raw_protocol_t;
typedef boost::asio::generic::basic_endpoint<raw_protocol_t> raw_endpoint_t;
boost::asio::io_service d_io_service10;
raw_protocol_t::socket *d_socket10;
/* 10G raw socket stuff */
udp_sink_impl.cc sminippet:
getMACAddress(d_send_iface,srcMAC);
/* Begin 1G management connection */
std::string s__port = (boost::format("%d") % port).str();
std::string s__host = host.empty() ? std::string("localhost") : host;
boost::asio::ip::udp::resolver resolver(d_io_service);
boost::asio::ip::udp::resolver::query query(s__host, s__port,
boost::asio::ip::resolver_query_base::passive);
d_endpoint = *resolver.resolve(query);
udpsocket = new boost::asio::ip::udp::socket(d_io_service);
udpsocket->connect(d_endpoint);
/* End 1G management connection */
/* Begin 10G management connection */
sockaddr_ll sockaddr;
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sll_family = PF_PACKET;
sockaddr.sll_protocol = htons(ETH_P_ALL);
sockaddr.sll_ifindex = if_nametoindex(send_iface.c_str());
sockaddr.sll_hatype = 1;
raw_protocol_t::socket d_socket10(d_io_service10, raw_protocol_t(PF_PACKET, SOCK_RAW)); /* Needs root or cap_net_raw permissions */
d_socket10.bind(raw_endpoint_t(&sockaddr, sizeof(sockaddr)));
/* End 10G management connection */
/* This currently does not work for unknown reason. Transmitted packet does NOT match buffer contents expected. But the streambuf seems to work. */
std::vector<boost::asio::const_buffer> transmitbuffer2;
transmitbuffer2.clear();
transmitbuffer2.push_back(boost::asio::buffer((const void *)srcMAC, sizeof(srcMAC)));
transmitbuffer2.push_back(boost::asio::buffer((const void *)dstMAC, sizeof(dstMAC)));
transmitbuffer2.push_back(boost::asio::buffer((const void *)custom_type, sizeof(custom_type)));
d_socket10.send(boost::asio::buffer(transmitbuffer2));
/* for testing */
boost::asio::streambuf buffer;
std::ostream stream( &buffer );
unsigned char const deadbeef[] = { 0xde, 0xad, 0xbe, 0xef }; // can't handle 0x00
stream << "Hello, World!!!"
<< reinterpret_cast< char const * >( deadbeef );
d_socket10.send(buffer.data());
} // Close constructor
.
.
.
udp_sink_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
.
.
.
udpsocket->send_to(transmitbuffer,d_endpoint);
最终,在UDP_SINK_IMPL ::工作功能我想替换现有的UDP调用:
udpsocket->send_to(transmitbuffer,d_endpoint);
与:
之类的东西d_socket10->send(transmitbuffer);
当前,当我这样做时,没有发送数据包,似乎会崩溃或退出程序,而不是连续发送数据,所以我认为这是某种崩溃。
有人可以向我解释如何实现简单堆栈溢出示例的指针或C 中的日语令牌的RAW套接字示例,用于UDP接收器/源块?接收器(发送)当前是我的优先级(接收)。
非常感谢。任何帮助或建议都非常感谢。
从散布收集io上的boost文档中,我认为发送的语法应该是:
d_socket10.send(transmitbuffer2); // don't add the extra boost::asio::buffer()
我找不到他们使用boost::asio::buffer
对缓冲区向量的任何示例
对于流测试,您必须使用write
成员功能而不是operator<<
在流中插入时指定大小。类似:
unsigned char const deadbeef[5] = { 0x00, 0xde, 0xad, 0xbe, 0xef };
stream.write(reinterpret_cast<const char*>(&deadbeef[0]), 5);
这样,您可以处理发送空字符。
您可以显示如何构建transmitbuffer
吗?它与transmitbuffer2
相同吗?
编辑
segfaults表示您尝试以非法方式访问内存。只能从您的片段中进行调试很难,但是我首先要检查您发送的缓冲区仍然有效。boost::asio::buffer
不会制作基础内存的副本,并且在您准备发送时需要保持有效。
您还会在摘要中混合指针和对象,因此请确保您没有任何悬挂的指针,并且每个人都处于有效状态,然后才能致电send
编辑2
在标题文件中,您声明了一个名为d_socket10
的成员指针,该指针从未在构造函数中分配或创建。此电话在第147行:
raw_protocol_t::socket d_socket10(d_io_service10, raw_protocol_t(PF_PACKET, SOCK_RAW));
创建一个与您的会员指针相同名称的对象,当您退出构造函数的范围时,该对象将被破坏。稍后,您使用从未分配任何东西的会员指针致电send
,因此您的segfault。
要修复它,您需要创建它并管理它的寿命,就像udpsocket
相同的方式:
d_socket10 = new raw_protocol_t::socket(d_io_service10, raw_protocol_t(PF_PACKET, SOCK_RAW));
并在不再需要时调用delete
。
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- 基于boost的程序的静态链接——zlib问题
- C++:如何在CLion IDE中安装Boost
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何在boost beast http请求中设置http头
- Boost Spirit,获取迭代器内部语义动作
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 使用Boost Interprocess创建托管共享内存需要很长时间
- Boost::posix_time::ptime舍入到给定的分钟数
- 使用boost asio在C 中发送layer2