X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/973f33d7adc7e95c773f7a9e73f281503385f69b..007694fe3d4ebd6577e1fb0a1017330b1a575a67:/src/surf/ns3/ns3_simulator.cc diff --git a/src/surf/ns3/ns3_simulator.cc b/src/surf/ns3/ns3_simulator.cc index 6c167db7da..199d6c68d6 100644 --- a/src/surf/ns3/ns3_simulator.cc +++ b/src/surf/ns3/ns3_simulator.cc @@ -7,12 +7,11 @@ #include "surf/ns3/ns3_simulator.h" #include "xbt/dict.h" #include "xbt/log.h" +#include "xbt/sysdep.h" using namespace ns3; using namespace std; -static const uint32_t writeSize = 1024; // limit the amout of data to write -uint8_t data[writeSize]; xbt_dict_t dict_socket = NULL; NS3Sim SimulatorNS3; @@ -55,9 +54,14 @@ void NS3Sim::create_flow_NS3( void * action) { if(!dict_socket) dict_socket = xbt_dict_new(); - PacketSinkHelper sink ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny(), port_number)); + + PacketSinkHelper sink ("ns3::TcpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny(), + port_number)); sink.Install (dst); - Ptr sock = Socket::CreateSocket (src, TypeId::LookupByName ("ns3::TcpSocketFactory")); + Ptr sock = Socket::CreateSocket (src, + TcpSocketFactory::GetTypeId()); + MySocket *mysocket = new MySocket(); mysocket->totalBytes = totalBytes; mysocket->remaining = totalBytes; @@ -99,57 +103,69 @@ void NS3Sim::simulator_start(void){ } static void receive_callback(Ptr localSocket){ - Address addr; - localSocket->GetSockName (addr); - InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr); MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); - mysocket->finished = 1; - //cout << "[" << Simulator::Now ().GetSeconds() << "] " << "Received [" << mysocket->totalBytes << "bytes], from: " << iaddr.GetIpv4 () << " port: " << iaddr.GetPort () << endl; - std::stringstream sstream; - sstream << Simulator::Now ().GetSeconds(); - std::string s = sstream.str(); - size_t size = s.size() + 1; - char * time_sec = new char[ size ]; - strncpy( time_sec, s.c_str(), size ); - XBT_DEBUG("Stop simulator at %s seconds",time_sec); - Simulator::Stop(); + if (mysocket->finished == 0){ + mysocket->finished = 1; +// cout << "[" << Simulator::Now ().GetSeconds() << "] " << "recv_cb of F[" << mysocket->totalBytes << "] " << endl; + XBT_DEBUG("Stop simulator at %f seconds", Simulator::Now().GetSeconds()); + Simulator::Stop(); + } } static void send_callback(Ptr localSocket, uint32_t txSpace){ - - Address addr; - localSocket->GetSockName (addr); - InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr); MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); - uint32_t totalBytes = mysocket->totalBytes; - while ((mysocket->bufferedBytes) < totalBytes && localSocket->GetTxAvailable () > 0){ - uint32_t toWrite = min ((mysocket->remaining), writeSize); - toWrite = min (toWrite, localSocket->GetTxAvailable ()); - int amountSent = localSocket->Send (&data[0], toWrite, 0); - - if(amountSent < 0) - return; - - (mysocket->bufferedBytes) += amountSent; - (mysocket->remaining) -= amountSent; - //cout << "[" << Simulator::Now ().GetSeconds() << "] " << "Send one packet, remaining "<< mysocket->remaining << " bytes!" << endl; + + if (mysocket->remaining == 0){ + //all data was already buffered (and socket was already closed), just return + return; } - if ((mysocket->bufferedBytes) >= totalBytes){ - localSocket->Close(); + + uint32_t toWrite = min (mysocket->remaining, txSpace); + uint8_t *data = (uint8_t*)malloc(sizeof(uint8_t)*toWrite); + int amountSent = localSocket->Send (&data[0], toWrite, 0); + free (data); + if (amountSent > 0){ + mysocket->bufferedBytes += amountSent; + mysocket->remaining -= amountSent; } +// cout << "[" << Simulator::Now ().GetSeconds() << "] " << "send_cb of F[" << mysocket->totalBytes << "] ("<< mysocket->remaining << " / " << mysocket->totalBytes << ") " << amountSent << " buffered." << endl; + if (mysocket->remaining == 0){ + //everything was buffered to send, tell NS3 to close the socket + localSocket->Close(); + } + return; } static void datasent_callback(Ptr localSocket, uint32_t dataSent){ - Address addr; - localSocket->GetSockName (addr); - InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr); MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); mysocket->sentBytes += dataSent; - //cout << "[" << Simulator::Now ().GetSeconds() << "] " << "DATASENT [" << mysocket->totalBytes << "bytes], from: " << iaddr.GetIpv4 () << " port: " << iaddr.GetPort () << " dataSent " << dataSent <totalBytes << "] " << dataSent << " sent." << endl; +} + +static void normalClose_callback(Ptr localSocket){ + MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); +// cout << "[" << Simulator::Now ().GetSeconds() << "] " << "normalClose_cb of F[" << mysocket->totalBytes << "]" << endl; + receive_callback (localSocket); +} + +static void errorClose_callback(Ptr localSocket){ + MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); +// cout << "[" << Simulator::Now ().GetSeconds() << "] " << "errorClose_cb of F[" << mysocket->totalBytes << "]" << endl; + xbt_die("NS3: a socket was closed anormally"); } +static void succeededConnect_callback(Ptr localSocket){ + MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); +// cout << "[" << Simulator::Now ().GetSeconds() << "] " << "succeededConnect_cb of F[" << mysocket->totalBytes << "]" << endl; +} + +static void failedConnect_callback(Ptr localSocket){ + MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); +// cout << "[" << Simulator::Now ().GetSeconds() << "] " << "failedConnect_cb of F[" << mysocket->totalBytes << "]" << endl; + xbt_die("NS3: a socket failed to connect"); +} static void StartFlow(Ptr sock, const char *to, @@ -157,10 +173,13 @@ static void StartFlow(Ptr sock, { InetSocketAddress serverAddr (to, port_number); - //cout << "[" << Simulator::Now().GetSeconds() << "] Starting flow to " << to << " using port " << port_number << endl; - sock->Connect(serverAddr); sock->SetSendCallback (MakeCallback (&send_callback)); sock->SetRecvCallback (MakeCallback (&receive_callback)); sock->SetDataSentCallback (MakeCallback (&datasent_callback)); + sock->SetConnectCallback (MakeCallback (&succeededConnect_callback), MakeCallback (&failedConnect_callback)); + sock->SetCloseCallbacks (MakeCallback (&normalClose_callback), MakeCallback (&errorClose_callback)); + + MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&sock); +// cout << "[" << Simulator::Now().GetSeconds() << "] Starting flow to " << to << " using port " << port_number << endl; }