NS3回调问题

来源:互联网 发布:mysql 配置用户名密码 编辑:程序博客网 时间:2024/06/05 16:11

最近学习了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呢?

0 0
原创粉丝点击