NS3回调问题
最近学习了Decload的关于NS3中socket的使用,想要稍作修改,发现自己实在是基础很不扎实,需要补补啊!
/* -*- 20160328 wsy 继续尝试 -*- */
/*
* 实现了client给server发送数据,server接收到后发回去给client,但当时
* client的socket已经关闭,无法正常接收
*
* 回调函数类似中断,用于检测对应socket有没有接收到内容,
* 接收到则跳进回调函数recvCallback中
*
*疑问:能不能在回调函数里再调用回调函数
*
*
*/
#include <fstream>
#include <string>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/mobility-module.h"
#include "ns3/config-store-module.h"
#include "ns3/wifi-module.h"
#include "ns3/internet-module.h"
#include "ns3/netanim-module.h"
using namespace ns3;
Ptr<Socket> server;
Ptr<Socket> client;
//Ptr<Packet> packet;
Ipv4InterfaceContainer i;
static void recvCallback(Ptr<Socket> sock)
{
Address Addr;
Ptr<Packet> packet = sock->RecvFrom(Addr);
std::cout << Addr <<std::endl;
std::cout << "size:" << packet->GetSize() << std::endl;
std::cout<<sock->SendTo(packet,0,Addr)<<std::endl;
// sleep(0.01);//本想用于等待一下,让client接收的,结果仅在开始的时候停止了一段时间,该函数在unistd.h中
std::cout<<client->Recv()<<std::endl;//接收失败,则返回0
}
static void recvCallback1(Ptr<Socket> sock) //用于检测在回调函数recvCallback中发送时,是否还能再调用回调,但好像因为client已经关闭,无法正常接收
{
std::cout<<"success11"<<std::endl;
Address Addr;
Ptr<Packet> packet = sock->RecvFrom(Addr);
std::cout << "size:" << packet->GetSize() << std::endl;
}
int main (int argc, char *argv[])
{
Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Mode", StringValue ("Time"));
Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Time", StringValue ("2s"));
Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Speed", StringValue ("ns3::ConstantRandomVariable[Constant=3.0]"));
Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Bounds", StringValue ("10|100|10|100"));
CommandLine cmd;
cmd.Parse (argc, argv);
NodeContainer c;
c.Create (2);
PacketMetadata::Enable();//这是跑代码过程中,报错提示添加的
WifiHelper wifi = WifiHelper::Default ();
wifi.SetStandard (WIFI_PHY_STANDARD_80211a);
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
wifiMac.SetType ("ns3::AdhocWifiMac");
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());//但凡定义了就一定要用上啊,要不会报错的!!SIGSEGV!!
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);
InternetStackHelper internet;
internet.Install (c);
Ipv4AddressHelper ipv4;
// NS_LOG_INFO ("Assign IP Addresses.");
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
i = ipv4.Assign (devices);
//---------------------------
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::RandomDiscPositionAllocator",
"X", StringValue ("30.0"),
"Y", StringValue ("30.0"),
"Rho", StringValue ("ns3::UniformRandomVariable[Min=5|Max=10]"));
mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
"Mode", StringValue ("Time"),
"Time", StringValue ("2s"),
"Speed", StringValue ("ns3::ConstantRandomVariable[Constant=3.0]"),
"Bounds", StringValue ("20|50|20|50"));
mobility.Install (c);
//Ipv4GlobalRoutingHelper::PopulateRoutingTables ();//这个是用广播模式,只有两个节点,且默认好像也是广播的,有资料说这个只能用在拓扑确定的网络,不是很懂
//server sockets
TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
server = Socket::CreateSocket(c.Get(0), tid);
InetSocketAddress addr = InetSocketAddress(Ipv4Address::GetAny(), 10086);
server->Bind(addr);
server->SetRecvCallback(MakeCallback(&recvCallback)); //设置回调函数
//client sockets
client = Socket::CreateSocket(c.Get(1), tid);
InetSocketAddress serverAddr = InetSocketAddress(i.GetAddress(0), 10086);
// client->Connect(serverAddr); //该语句好像只是确定了一方的地址,使用该套接字不用再制定地址和端口号,原本是用于TCP的
client->Bind(addr);
client->SetRecvCallback(MakeCallback(&recvCallback1));
client->SendTo(Create<Packet>(500),0,serverAddr);
std::cout << serverAddr <<std::endl;
std::cout<<client->Close()<<std::endl;//输出为0表示关闭成功,否则为-1。不关闭client,或者在if语句中关闭回调都会报错。
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
代码是自己乱改的,如有问题,感谢指出!
存在问题:如何能够在client->server->client过程完成后再关闭socket呢?