質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3442閲覧

NS-3に関してクラスのエラー

marny

総合スコア19

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/07/09 09:14

###前提・実現したいこと
NS-3というネットワークシミュレーションソフトを使用しており,
複数のノードをパケットが巡回していくというシステムを作っています.
EtherCATクラスを作って,それを実行しようとしたところ以下のようなエラーが発生し,詰まっております.
NS3やC++を始めて数週間程度でして,指定されている箇所と,エラーメッセージのInetSocketAddress関数の関わりがよくわからない状態です.詳しい方おられましたらなにとぞよろしくお願いいたします.

###発生している問題・エラーメッセージ
../scratch/test04_csmaclass.cc: In constructor ‘EtherCAT::EtherCAT()’:
../scratch/test04_csmaclass.cc:84:20: error: no matching function for call to ‘ns3::InetSocketAddress::InetSocketAddress()’
EtherCAT::EtherCAT()
^
In file included from ./ns3/network-module.h:31:0,
from ../scratch/test04_csmaclass.cc:2:
./ns3/inet-socket-address.h:70:3: note: candidate: ns3::InetSocketAddress::InetSocketAddress(const char*)
InetSocketAddress (const char ipv4);
^
./ns3/inet-socket-address.h:70:3: note: candidate expects 1 argument, 0 provided
./ns3/inet-socket-address.h:64:3: note: candidate: ns3::InetSocketAddress::InetSocketAddress(const char
, uint16_t)
InetSocketAddress (const char *ipv4, uint16_t port);
^
./ns3/inet-socket-address.h:64:3: note: candidate expects 2 arguments, 0 provided
./ns3/inet-socket-address.h:59:3: note: candidate: ns3::InetSocketAddress::InetSocketAddress(uint16_t)
InetSocketAddress (uint16_t port);
^
./ns3/inet-socket-address.h:59:3: note: candidate expects 1 argument, 0 provided
./ns3/inet-socket-address.h:53:3: note: candidate: ns3::InetSocketAddress::InetSocketAddress(ns3::Ipv4Address)
InetSocketAddress (Ipv4Address ipv4);
^
./ns3/inet-socket-address.h:53:3: note: candidate expects 1 argument, 0 provided
./ns3/inet-socket-address.h:47:3: note: candidate: ns3::InetSocketAddress::InetSocketAddress(ns3::Ipv4Address, uint16_t)
InetSocketAddress (Ipv4Address ipv4, uint16_t port);
^
./ns3/inet-socket-address.h:47:3: note: candidate expects 2 arguments, 0 provided
./ns3/inet-socket-address.h:40:7: note: candidate: ns3::InetSocketAddress::InetSocketAddress(const ns3::InetSocketAddress&)
class InetSocketAddress
^
./ns3/inet-socket-address.h:40:7: note: candidate expects 1 argument, 0 provided

###該当のソースコード
言語はC++です.
using namespace ns3;
using namespace std;

define packet_size 1024

class EtherCAT {

public:
EtherCAT();
virtual void CreateTopology();
virtual void ConfigureDataLinkLayer();
virtual void ConfigureNetworkLayer();
virtual void ConfigureTransportLayer();
virtual void MakePacket();
virtual void SendFirstPacket();
virtual void ConfigureAnimation();
Ptr<Node> *n;
uint32_t node_num;
InetSocketAddress setSocketAddress(Ptr<Node>node,uint16_t port);

private:
void SendPacket(Ptr<Packet>packet,Ptr<Socket>socket,InetSocketAddress toadd);
void ReceivePacket(Ptr<Socket>socket);

NodeContainer csmaNodes; NetDeviceContainer csmaDevices; Ptr<Socket> MasSourceSocket; Ptr<Socket> MasRecvSocket; Ptr<Socket> Sla1SourceSocket; Ptr<Socket> Sla1RecvSocket; Ptr<Socket> Sla2SourceSocket; Ptr<Socket> Sla2RecvSocket; Ptr<Packet> packet; InetSocketAddress Sla1RecvSocketAddr;

};

EtherCAT::EtherCAT()
{

}

//ソケットアドレスを決定する
InetSocketAddress EtherCAT::setSocketAddress(Ptr<Node> node,uint16_t port)
{
Ipv4InterfaceAddress addr = node->GetObject <Ipv4> ()->GetAddress(1, 0);
return InetSocketAddress (Ipv4Address(addr.GetLocal()), port);
}
//トポロジーをつくる
void EtherCAT::CreateTopology()
{
n = new Ptr<Node> [node_num];
for(size_t i=0;i<node_num;++i){
n[i] = CreateObject<Node>();
csmaNodes.Add(n[i]);
}
}

//データリンク(物理)層のプロトコルを決める
void EtherCAT::ConfigureDataLinkLayer()
{
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("10Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (5000)));

//Ptr<CsmaChannel> csmaChannel = CreateObject<CsmaChannel>();

csmaDevices = csma.Install (csmaNodes);
}

//ネットワーク層のプロトコルを決める
void EtherCAT::ConfigureNetworkLayer()
{
InternetStackHelper stack;
stack.Install(csmaNodes);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0","0.0.0.1");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = address.Assign(csmaDevices);
}

//ソケットを作り送信時と受信時の動作を決める
void EtherCAT::ConfigureTransportLayer()
{
TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");

//master
MasSourceSocket = Socket::CreateSocket(n[0],tid);
MasRecvSocket = Socket::CreateSocket(n[0],tid);
InetSocketAddress MasSourceSocketAddr = EtherCAT::setSocketAddress(n[0],10);
InetSocketAddress MasRecvSocketAddr = EtherCAT::setSocketAddress(n[0],9);
MasSourceSocket->Bind(MasSourceSocketAddr);
MasRecvSocket->Bind(MasRecvSocketAddr);

//slave-1
Sla1RecvSocket = Socket::CreateSocket(n[1],tid);
InetSocketAddress Sla1SourceSocketAddr = EtherCAT::setSocketAddress(n[1],10);
Sla1RecvSocketAddr = setSocketAddress(n[1],9);
Sla1SourceSocket->Bind(Sla1SourceSocketAddr);
Sla1RecvSocket->Bind(Sla1RecvSocketAddr);
Sla1RecvSocket->SetRecvCallback(MakeCallback(&EtherCAT::ReceivePacket,this));

//slave-2
Sla2RecvSocket = Socket::CreateSocket(n[2],tid);
InetSocketAddress Sla2SourceSocketAddr = EtherCAT::setSocketAddress(n[2],10);
InetSocketAddress Sla2RecvSocketAddr = EtherCAT::setSocketAddress(n[2],9);
Sla2SourceSocket->Bind(Sla2SourceSocketAddr);
Sla2RecvSocket->Bind(Sla2RecvSocketAddr);
Sla2RecvSocket->SetRecvCallback(MakeCallback(&EtherCAT::ReceivePacket,this));

MasSourceSocket->Connect(Sla1RecvSocketAddr);
}

//パケットを作る
void EtherCAT::MakePacket()
{
uint8_t buf[packet_size];
std::string greeting_msg = "testMessage";
memcpy(buf,greeting_msg.c_str(),greeting_msg.size());
packet = Create<Packet>(buf,packet_size);
}

//初めのパケットを送る
void EtherCAT::SendFirstPacket()
{
EtherCAT::SendPacket(packet,MasSourceSocket,Sla1RecvSocketAddr);
}

//パケット送信
void EtherCAT::SendPacket(Ptr<Packet> packet,Ptr<Socket> socket,InetSocketAddress toadd)
{
uint32_t a=0;
socket->SendTo(packet,a,toadd);
cout << "send a packet." << endl;
}

//パケット受信時
void EtherCAT::ReceivePacket(Ptr<Socket> socket)
{
TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
Ptr<Packet> packet;
Address from;
uint8_t buf[packet_size];

memset(buf,0,sizeof(buf));
while((packet = socket->RecvFrom(from)))
{
if (packet->GetSize()>0)
{
Ptr<Node> recvnode = socket->GetNode();
Ptr<Ipv4> ipv4 = recvnode->GetObject<Ipv4>();
Ipv4Address Toaddr = ipv4->GetAddress(
ipv4->GetInterfaceForDevice(
ipv4->GetNetDevice(1)),0).GetLocal();//受信ノードのアドレス

packet->CopyData(buf,packet_size); InetSocketAddress iaddr = InetSocketAddress::ConvertFrom(from); Ipv4Address Fromaddr = iaddr.GetIpv4();//送信元のアドレス std::cout << std::setw(10) << Simulator::Now().GetSeconds() << "received" << "from:(" << Fromaddr <<")" << "To:(" << Toaddr << ")" <<"----"<< &buf[0] << endl << &buf[200] << std::endl; if(Toaddr == "10.1.1.2") { if(Fromaddr == "10.1.1.1") { Ptr<Socket> SourceSocket = Socket::CreateSocket(n[1],tid); InetSocketAddress NextToSocketAddr = EtherCAT::setSocketAddress(n[2],10); SourceSocket->Connect(NextToSocketAddr); EtherCAT::SendPacket(packet,SourceSocket,NextToSocketAddr); cout << "sended second packet." << endl; } if(Fromaddr == "10.1.1.3") { } } if(Toaddr == "10.1.1.3") { if(Fromaddr == "10.1.1.2") { Ptr<Socket> SourceSocket = Socket::CreateSocket(n[2],tid); InetSocketAddress NextToSocketAddr = EtherCAT::setSocketAddress(n[1],10); SourceSocket->Connect(NextToSocketAddr); EtherCAT::SendPacket(packet,SourceSocket,NextToSocketAddr); cout << "sended third packet." << endl; } } } }

}

//アニメーションノード設定
void EtherCAT::ConfigureAnimation()
{
AnimationInterface::SetConstantPosition(csmaNodes.Get(0),0.0,3.0);
AnimationInterface::SetConstantPosition(csmaNodes.Get(1),3.0,3.0);
AnimationInterface::SetConstantPosition(csmaNodes.Get(2),6.0,3.0);

}

int main (int argc, char **argv)
{
EtherCAT EtherCAT;
EtherCAT.node_num = 3;
EtherCAT.CreateTopology();
EtherCAT.ConfigureDataLinkLayer();
EtherCAT.ConfigureNetworkLayer();
EtherCAT.ConfigureTransportLayer();

EtherCAT.MakePacket();
EtherCAT.SendFirstPacket();
EtherCAT.ConfigureAnimation();
std::string AnimFile = "test04_class.xml";
AnimationInterface anim(AnimFile);
anim.EnablePacketMetadata(true);

Simulator::Stop(Seconds(10));
Simulator::Run();
Simulator::Destroy();
return 0 ;
}

###試したこと
指示されていると思われるコンストラクタはなくてもいけるのではと考え,消してみましたがダメでした.

###補足情報(言語/FW/ツール等のバージョンなど)
InetSocketAddressとはNS3ツールでのクラスです.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

C++のクラスが、クラス型のメンバ変数を持つ場合、コンストラクタでそのクラス型のメンバ変数が初期化されます。

EtherCATクラスは、InetSocketAddressクラス型のメンバ変数Sla1RecvSocketAddrを持っています。
これが、EtherCATクラスのデフォルト・コンストラクタで初期化されますが、明示的に指定していないため、InetSocketAddressのデフォルト・コンストラクタで初期化されます。

しかし、恐らく、InetSocketAddressクラスにはデフォルト・コンストラクタが定義されておらず、「適切なコンストラクタが見つからない」エラーが出ています。

InetSocketAddressにデフォルト・コンストラクタを定義するか、EtherCATクラスのデフォルト・コンストラクタでInetSocketAddressの存在するコンストラクタを明示的に呼び出して、初期化すれは良いと思います。

例えば、後者の場合は、以下のイメージです。

C++

1EtherCAT::EtherCAT() : Sla1RecvSocketAddr("IPv4アドレス") 2{ 3 4}

投稿2017/07/09 09:27

編集2017/07/09 12:09
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marny

2017/07/09 11:19

返信くださりありがとうございます. 書き換えてみたところ type ‘ns3::InetSocketAddress’ is not a direct base of ‘EtherCAT’ というメッセージが表示されました.直接のベースではないとはどういう意味なのでしょうか. その後,Sla1RecvSocketAddrの宣言をメンバ関数内(ConfigureTransportLayer)に入れてみてもいいのではないかと考え,そしてmain文でSendFirstPacketをSendPacketに書き換え,SendPacket(EtherCAT.packet,EtherCAT.MasSourceSocket,??)この3つ目の引数をEtherCATクラスのConfigureTransportLayerメンバ関数内にあるSla1SourceSocketAddrを持ってきたいのですが,??をどのように書けばいいでしょうか? ...正しく伝えられているか怪しいかもしれませんが,よろしくお願いいたします.
Chironian

2017/07/09 12:11 編集

あっとと、ごめんなさい。間違って書いてました。 InetSocketAddressではなくSla1RecvSocketAddrでした。 回答を修正します。 > その後,Sla1RecvSocketAddrの宣言をメンバ関数内 に関してはごめんなさい。今日の暑さとソースが長くてちゃんと読む根性がありません。 あ、後、回答欄の上の方にある<code>を押して表示される```の間にソースを貼り付けると、インデントも残るので読みやすくなりますよ。
marny

2017/07/09 13:15

いえいえ! 初めて質問させていただいたので,見にくい点も多々あったと思いますが,回答してくださりありがとうございました. とりあえず,メンバ関数に入れてエラーは取れたのですが1度送信して以降巡回はまだできていないのでReceivePacketの再帰を入念に調べたいと思います.ありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問