Popular Posts

Total Pageviews

Wednesday, December 15, 2010

How to send user data in ns2

If you are trying to send your own data (i.e user defined data) over a network in ns2 then you might have tried different function of Packet. If you have tried out allocating PacketData and setting it into Packet then it might have leaking the memory and eats up swap space and later processor time too. Generally for small data transfer it wont be able to figure it out but when you transfer data in order of 10 of MBs then you might face this challenge. You might have tried creating your own Packet type etc. if it works then its good but i don't think it will.
So what we can do?

Solution is that create your own application layer and transport layer well you can edit existing but those are might be used by other traffics and did not give proper results in other application which you don't want. Its always nice to create a new class. So derive a class from application layer and another class from transport layer.
Add one char * data and int size field in packet header.

In application read data from file and assign it to new pointer, create a packet and point data field of packet to this new pointer with size and send this packet to transport layer. At transport layer copy the packet header into newly created header (all existing transport layer always create a new packet) and send it normally to other existing layers with out any problem.

On receiving at transport layer either you can process it here or pass the header to application layer for further process. Now process the data in receive side of application layer and free the pointer pointed by data pointer of header. That's it and you are done.

Here goes the important part of the code but this is for UDP, similar things can be done on TCP (TCP code will look complex that's why i am uploading UDP code)
void mimoUdpAgent::sendmsg(int nbytes, AppData* data, const char* flags)
{
    Packet *p;
    int n;
    hdr_cmn cmn_buf = *(hdr_cmn *)flags;
    assert (size_ > 0);

    n = nbytes / size_;

    if (nbytes == -1) {
        printf("Error:  sendmsg() for UDP should not be -1\n");
        return;
    }   

    // If they are sending data, then it must fit within a single packet.
    if (data && nbytes > size_) {
        printf("Error: data greater than maximum UDP packet size\n");
        return;
    }

    double local_time = Scheduler::instance().clock();
    while (n-- > 0) {
        p = allocpkt();
        hdr_cmn::access(p)->size() = size_;
        hdr_rtp* rh = hdr_rtp::access(p);
        rh->flags() = 0;
        rh->seqno() = ++seqno_;
        hdr_cmn::access(p)->timestamp() =
            (u_int32_t)(SAMPLERATE*local_time);
       
        hdr_cmn::access(p)->last_ = cmn_buf.last_;
       
        hdr_cmn::access(p)->realPayload = cmn_buf.realPayload;
        hdr_cmn::access(p)->file = cmn_buf.file;
        hdr_cmn::access(p)->frame_id_ = cmn_buf.frame_id_;
        char buf[100];
        if(openfile!=0){
            hdr_cmn::access(p)->pkt_id_ = id_++;
        }
       
        // add "beginning of talkspurt" labels (tcl/ex/test-rcvr.tcl)
        if (flags && (0 ==strcmp(flags, "NEW_BURST")))
            rh->flags() |= RTP_M;
        p->setdata(data);
        target_->recv(p);
    }
    n = nbytes % size_;
    if (n > 0) {
        p = allocpkt();
        hdr_cmn::access(p)->size() = n;
        hdr_rtp* rh = hdr_rtp::access(p);
        rh->flags() = 0;
        rh->seqno() = ++seqno_;
        hdr_cmn::access(p)->timestamp() =
            (u_int32_t)(SAMPLERATE*local_time);
        hdr_cmn::access(p)->last_ = cmn_buf.last_;
        hdr_cmn::access(p)->realPayload = cmn_buf.realPayload;

        hdr_cmn::access(p)->file = cmn_buf.file;
        if (flags && (0 == strcmp(flags, "NEW_BURST")))
            rh->flags() |= RTP_M;
        p->setdata(data);
        target_->recv(p);
    }
    idle();
}
Note: Part of the code is copied from work of other person.

I have added many fields here but realPayload and last are important field. Last will tell the end of data and realPayload contains actual data transferred from application.