#include #include #include #include #include #include #include #include #include "ns3/core-module.h" #include "ns3/helper-module.h" #include "ns3/node-module.h" #include "ns3/global-route-manager.h" #include "ns3/simulator-module.h" using namespace ns3; std::string rle(const std::string &s); std::string rle(const std::string &s, int maxsize); std::string rle(const std::string &s, int maxsize,int justify); //------------- Tag ------------------------ class Atag : public Tag { public: Atag(); Atag(uint32_t); static uint32_t GetUid (void); void Print (std::ostream &os) const; uint32_t GetSerializedSize (void) const; void Serialize (Buffer::Iterator) const; uint32_t Deserialize (Buffer::Iterator); uint32_t GetValue(void) const; void SetValue(uint32_t); private: uint32_t value; }; Atag::Atag() : value(0) { } Atag::Atag(uint32_t v_) : value(v_) { // value = v_; } uint32_t Atag::GetUid (void) { static uint32_t uid = AllocateUid ("Atag.test"); return uid; } void Atag::SetValue(uint32_t v_) { value = v_; } uint32_t Atag::GetValue(void) const { return value; } void Atag::Print (std::ostream &os) const { os << "(tag=" << value << ")"; } uint32_t Atag::GetSerializedSize (void) const { return sizeof(value); } void Atag::Serialize (Buffer::Iterator i) const { i.WriteU32 (value); } uint32_t Atag::Deserialize (Buffer::Iterator i) { value = i.ReadU32 (); return sizeof(value); } //------------- Application ------------------------ class TalkerApp : public Application { public: TalkerApp(); virtual ~TalkerApp (); void ConfRecv(Ptr, const Address,int); void ConfSend(Ptr, const Address,int); protected: virtual void DoDispose (void); private: virtual void StartApplication (void); virtual void StartApplicationRecv (void); virtual void StartApplicationSend (void); virtual void StopApplication (void); virtual void Receive (Ptr socket, Ptr packet, const Address& from); void SendPacket(std::string,int,int); virtual void CloseConnection (Ptr socket); void ConnectionSucceeded(Ptr); void ConnectionFailed(Ptr); void ConnectionHalfClosed(Ptr); bool ConnectionRequested(Ptr, const Address &); void ConnectionCreated(Ptr, const Address &); void ConnectionCloseRequested(Ptr); Ptr m_socket; Ptr m_servsocket; Address m_local; Address m_remote; int i_am_listener; int recv_cnt; int m_send_size; int m_recv_size; std::map m_keycounter; }; TalkerApp::TalkerApp () : m_socket(0), m_servsocket(0), recv_cnt(0), m_send_size(0), m_recv_size(0) {} TalkerApp::~TalkerApp() {} void TalkerApp::DoDispose (void) { m_socket = 0; m_servsocket = 0; Application::DoDispose (); } void TalkerApp::ConnectionSucceeded(Ptr sock) { std::cout << "TalkerApp::ConnectionSucceeded(): " << (i_am_listener ? "Server" : "Client") << std::endl; } void TalkerApp::ConnectionFailed(Ptr sock) { std::cout << "TalkerApp::ConnectionFailed(): " << (i_am_listener ? "Server" : "Client") << std::endl; } void TalkerApp::ConnectionHalfClosed(Ptr sock) { std::cout << "TalkerApp::ConnectionHalfClosed(): " << (i_am_listener ? "Server" : "Client") << std::endl; } bool TalkerApp::ConnectionRequested(Ptr sock, const Address &addr) { std::cout << "TalkerApp::ConnectionRequested(): " << (i_am_listener ? "Server" : "Client") << std::endl; return(1); } void TalkerApp::ConnectionCreated(Ptr sock, const Address &addr) { std::cout << "TalkerApp::ConnectionCreated(): " << (i_am_listener ? "Server" : "Client") << std::endl; m_socket = sock; m_socket->SetRecvCallback (MakeCallback(&TalkerApp::Receive, this)); } void TalkerApp::ConnectionCloseRequested(Ptr sock) { std::cout << "TalkerApp::ConnectionCloseRequested(): " << (i_am_listener ? "Server" : "Client") << std::endl; } void TalkerApp::StartApplication() { std::cout << "TalkerApp::StartApplication() " << (i_am_listener ? "Server" : "Client") << std::endl; if (i_am_listener) StartApplicationRecv(); else StartApplicationSend(); } void TalkerApp::StartApplicationSend() { std::cout << "TalkerApp::StartApplicationSend() " << (i_am_listener ? "Server" : "Client") << std::endl; if (!m_socket) { Ptr socketFactory = GetNode ()->GetObject (TypeId::LookupByName ("ns3::Tcp")); m_socket = socketFactory->CreateSocket (); m_socket->Bind (); } m_socket->Connect (m_remote); m_socket->SetConnectCallback ( MakeCallback(&TalkerApp::ConnectionSucceeded,this), MakeCallback(&TalkerApp::ConnectionFailed,this), MakeCallback(&TalkerApp::ConnectionHalfClosed,this) ); m_socket->SetRecvCallback (MakeCallback(&TalkerApp::Receive, this)); SendPacket(std::string("SHello"),'S',m_send_size); } void TalkerApp::StartApplicationRecv() { std::cout << "TalkerApp::StartApplicationRecv() " << (i_am_listener ? "Server" : "Client") << std::endl; if (!m_servsocket) { Ptr socketFactory = GetNode ()->GetObject (TypeId::LookupByName ("ns3::Tcp")); m_servsocket = socketFactory->CreateSocket (); m_servsocket->Bind (m_local); m_servsocket->Listen (0); } m_servsocket->SetAcceptCallback ( MakeCallback(&TalkerApp::ConnectionRequested,this), MakeCallback(&TalkerApp::ConnectionCreated,this), MakeCallback(&TalkerApp::ConnectionCloseRequested,this) ); } void TalkerApp::ConfRecv(Ptr node, const Address addr,int size) { i_am_listener = 1; std::cout << "TalkerApp::ConfRecv(" << node << "," << addr << "," << size << ") " << (i_am_listener ? "Server" : "Client") << std::endl; m_local = addr; m_recv_size = size; node->AddApplication(this); } void TalkerApp::ConfSend(Ptr node, const Address addr,int size) { i_am_listener = 0; std::cout << "TalkerApp::ConfSend(" << node << "," << addr << "," << size << ") " << (i_am_listener ? "Server" : "Client") << std::endl; m_remote = addr; m_send_size = size; node->AddApplication(this); } void TalkerApp::SendPacket(std::string label,int fill,int size) { uint8_t *mybuf = new uint8_t[size]; memset(mybuf,fill,size); std::cout << "writing buffer " << "(" << label << ") " << (i_am_listener ? "Server" : "Client") << std::endl; if (size > 1) { char *mybufc = reinterpret_cast(mybuf); snprintf(mybufc,size,"%s",label.c_str()); } m_socket->Send (mybuf, size); } void TalkerApp::StopApplication() { if (m_socket) m_socket->SetRecvCallback (MakeNullCallback, Ptr, const Address &> ()); } void TalkerApp::Receive(Ptr socket, Ptr packet, const Address &from) { if (InetSocketAddress::IsMatchingType (from)) { InetSocketAddress address = InetSocketAddress::ConvertFrom (from); uint8_t key = *(packet->PeekData()); m_keycounter[key] += packet->GetSize(); std::cout << "Received " << std::setw(4) << packet->GetSize() << " bytes from " << address.GetIpv4() << " [" << address << "] "; //packet->Print(std::cout << " "); //packet->PrintTags(std::cout); std::string buf = std::string((char *)packet->PeekData()); int buf_size = (buf.size() < packet->GetSize() ? buf.size() : packet->GetSize()); std::cout << " " << std::setw(15) << std::left << rle(buf,buf_size,3) << " " << key << "(" << std::setw(6) << std::right << m_keycounter[key] << ")"; std::cout << std::endl; if (i_am_listener && recv_cnt++ == 0) { SendPacket(std::string("RBackAtYou"),'R', m_recv_size); } } else { std::cout << "TalkerApp::Receive(): not matching." << std::endl; } } void TalkerApp::CloseConnection (Ptr socket) { std::cout << "TalkerApp::CloseConnection(): " << (i_am_listener ? "Server" : "Client") << std::endl; socket->Close (); } std::string rle(const std::string &s) { return(rle(s,s.size())); } std::string rle(const std::string &s, int maxsize) { return(rle(s,maxsize,0)); } std::string rle(const std::string &s, int maxsize,int justify) { std::ostringstream o; const char min_rep = 3; char cur_char = 0; int cur_cnt = 0; if (justify) { o << std::setw(justify) << std::right << maxsize << ":"; } else { o << maxsize << ":"; } for (int i = 0; i < maxsize; i++) { if (s[i] == cur_char) cur_cnt++; else { if (cur_cnt >= min_rep) o << cur_char << "{" << cur_cnt << "}"; else for (int irep=0; irep < cur_cnt; irep++) o << cur_char; cur_char = s[i]; cur_cnt = 1; } } if (cur_cnt >= min_rep) o << cur_char << "{" << cur_cnt << "}"; else for (int irep=0; irep < cur_cnt; irep++) o << cur_char; return o.str(); } int main (int argc, char *argv[]) { int send_size = 600; int recv_size = 700; if (argc == 3) { send_size = atoi(argv[1]); recv_size = atoi(argv[2]); } RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); Packet::EnableMetadata(); NodeContainer c0; c0.Create (2); // We create the channels first without any IP addressing information PointToPointHelper p2p; p2p.SetChannelParameter ("BitRate", DataRate(10000000)); p2p.SetChannelParameter ("Delay", MilliSeconds(10)); NetDeviceContainer dev0 = p2p.Install (c0); // add ip/tcp stack to nodes. InternetStackHelper internet; internet.Install (c0); // Later, we add IP addresses. Ipv4AddressHelper ipv4; ipv4.SetBase ("10.1.0.0", "255.255.255.0"); Ipv4InterfaceContainer ifaces = ipv4.Assign (dev0); // Configure the apps. uint16_t servPort = 32; TalkerApp source; source.ConfSend(c0.Get(0), InetSocketAddress (ifaces.GetAddress (1), servPort),send_size); source.Start(Seconds(0.0)); TalkerApp sink; sink.ConfRecv(c0.Get(1), InetSocketAddress (Ipv4Address::GetAny(), servPort), recv_size); sink.Start (Seconds (0.0)); #if 0 std::ofstream ascii; ascii.open ("tcp-tester.tr"); PointToPointHelper::EnableAscii (ascii); InternetStackHelper::EnablePcap ("tcp-tester"); #endif Simulator::StopAt (Seconds(10)); //LogComponentEnableAll (ns3::LOG_ALL); //Simulator::EnableLogTo("tcp-tester.tr"); Simulator::Run (); Simulator::Destroy (); }