[英]Linux Multicast Subsequent Socket Steals Data
我正在嘗試使用Boost ASIO UDP套接字來多播數據。 我相信我的發送者和接收者都可以正常工作,因為單個發送者和接收者都可以正常工作。 但是,當我們現在在同一台計算機上有多個接收器時,只有最后綁定到該地址的接收器才可以接收數據。 我相信這可能是配置問題,但是我將盡一切可能。
網絡:
[root@dev ~]# ifconfig
eth1 Link encap:Ethernet HWaddr 00:0C:29:C1:34:B7
inet addr:192.168.6.131 Bcast:192.168.6.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fec1:34b7/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:25060380 errors:0 dropped:0 overruns:0 frame:0
TX packets:24562809 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2030905679 (1.8 GiB) TX bytes:5249474660 (4.8 GiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:2687213321 errors:0 dropped:0 overruns:0 frame:0
TX packets:2687213321 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1633558802477 (1.4 TiB) TX bytes:1633558802477 (1.4 TiB)
組播發送方:
MulticastSender(const std::string& listenaddress,
const std::string& multicastaddress,
const unsigned short port) : Address(boost::asio::ip::address::from_string(listenaddress)),
Port(port),
Endpoint(Address, port),
Socket(IOService, Endpoint.protocol()),
Work(IOService) {
Socket.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string(multicastaddress).to_v4(), boost::asio::ip::address::from_string(listenaddress).to_v4()));
auto self = this;
WorkThread = std::thread([self]()
{
self->IOService.run();
});
}
組播接收器:
MulticastReceiver(const std::string &listenaddress,
const std::string &multicastaddress,
const unsigned short port) : Socket(IOService),
ListenAddress(listenaddress),
MulticastAddress(multicastaddress),
Work(IOService) {
boost::asio::ip::udp::endpoint listenendpoint(boost::asio::ip::udp::v4(), port);
boost::system::error_code ec;
Socket.open(listenendpoint.protocol(), ec);
Socket.set_option(boost::asio::ip::udp::socket::reuse_address(true), ec);
Socket.set_option(boost::asio::ip::multicast::enable_loopback(true), ec);
Socket.bind(listenendpoint, ec);
Socket.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string(multicastaddress).to_v4(), boost::asio::ip::address::from_string(listenaddress).to_v4()), ec);
auto self = this;
WorkThread = std::thread([self]()
{
self->IOService.run();
});
Socket.async_receive_from(boost::asio::buffer(Buffers[BufferIndex], MaxLength), Endpoint,
boost::bind(&MulticastReceiver::HandleReceiveFrom, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
對於listenaddress
我嘗試了使用192.168.6.131
指定接口,還嘗試了使用0.0.0.0
將其留給系統。 我還嘗試了join_group
兩種變體, join_group
在其中指定接口或不指定接口。
當我運行應用程序時,運行netstat -gn時,可以在正確的地址中看到正確的成員數。
這是我對發送者和接收者的輸入:
listenaddress = "0.0.0.0"; // or listenaddress = "192.168.6.131"; // eth1
multicastaddress = "239.140.127.0";
port = 35000;
我正在CentOS 6.6 with kernel Linux dev 2.6.32-504.el6.x86_64
運行此程序,並運行Boost 1.55.0
。
我無法弄清楚為什么多播不能在該設置上工作,但是我能夠使代碼在其他地方工作,所以我想我也可以將更改發送給發送方和接收方。
組播發送方:
MulticastSender(const std::string& multicastaddress,
const unsigned short port) : Port(port),
Endpoint(boost::asio::ip::address::from_string(multicastaddress), port),
Socket(IOService, Endpoint.protocol()),
Work(IOService) {
auto self = this;
WorkThread = std::thread([self]()
{
self->IOService.run();
});
std::string data = "Test message";
Socket.async_send_to(boost::asio::buffer(data), Endpoint, boost::bind(&MulticastSender::SendHandler, this, boost::asio::placeholders::error));
}
組播接收器:
MulticastReceiver(const std::string &listenaddress,
const std::string &multicastaddress,
const unsigned short port,
const int numbuffers) : Socket(IOService),
ListenAddress(listenaddress),
MulticastAddress(multicastaddress),
Work(IOService) {
boost::asio::ip::udp::endpoint listenendpoint(boost::asio::ip::address::from_string(listenaddress), port);
boost::system::error_code ec;
Socket.open(listenendpoint.protocol(), ec);
Socket.set_option(boost::asio::ip::udp::socket::reuse_address(true), ec);
Socket.set_option(boost::asio::ip::multicast::enable_loopback(true), ec);
Socket.bind(listenendpoint, ec);
Socket.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string(multicastaddress)), ec);
auto self = this;
WorkThread = std::thread([self]()
{
self->IOService.run();
});
Socket.async_receive_from(boost::asio::buffer(Buffers[BufferIndex], MaxLength), Endpoint,
boost::bind(&MulticastReceiver::HandleReceiveFrom, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.