⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mftp_snd.cc

📁 在ns-2添加apps
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * (c) 1997-98 StarBurst Communications Inc. * * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Author: Christoph Haenle, chris@cs.vu.nl * File: mftp_snd.cc * Last change: Dec 07, 1998 * * This software may freely be used only for non-commercial purposes * * $Header: /nfs/jade/vint/CVSROOT/ns-2/apps/mftp_snd.cc,v 1.9 2000/09/01 03:04:06 haoboy Exp $ */// This file contains functionality specific to the MFTP sender.#include <stdlib.h>     // strtoul, etc.#include <assert.h>#include <stdio.h>#include "config.h"#include "tclcl.h"#include "agent.h"#include "packet.h"#include "ip.h"#include "mftp_snd.h"#include "trace.h"#include "bitops.h"       // due to IS_BITSET, etc.#define min(a, b)       ((a) < (b) ? (a) : (b))static class MFTPSndAgentClass : public TclClass {public:    MFTPSndAgentClass() : TclClass("Agent/MFTP/Snd") {}    TclObject* create(int, const char*const*) {        return (new MFTPSndAgent());    }} class_mftpsnd_agent;int hdr_mftp::offset_;static class MFTPHeaderClass : public PacketHeaderClass {public:    MFTPHeaderClass() : PacketHeaderClass("PacketHeader/MFTP",                                          sizeof(hdr_mftp)) {	    bind_offset(&hdr_mftp::offset_);    }} class_mftphdr;MFTPSndAgent::MFTPSndAgent()    : MFTPAgent(),      naks(0),      retx(0),      fseek_offset(0),      read_ahead_bufsize(0),      CurrentPass(0),      CurrentGroup(0),      CwPat(0),      MinGroupNbInBuf(0),      NbGroupsInBuf(0){    bind("readAheadBufsize_", &readAheadBufsize_);    bind_time("txStatusDelay_", &txStatusDelay_);    bind("nakCount_", &nakCount_);}MFTPSndAgent::~MFTPSndAgent(){    delete [] naks;  // NOTE: delete on NULL pointer has no effect    delete [] retx;}int MFTPSndAgent::command(int argc, const char*const* argv){    Tcl& tcl = Tcl::instance();    if(strcmp(argv[1], "send") == 0) {        if(strcmp(argv[2], "data") == 0) {            return send_data();        } else if(strcmp(argv[2], "statreq") == 0) {            unsigned long pass_nb, block_lo, block_hi;            double rsp_backoff_window=2343.2343;            int nb_scanned = 0;            if(argc == 7) {                nb_scanned += sscanf(argv[3], "%lu", &pass_nb);                nb_scanned += sscanf(argv[4], "%lu", &block_lo);                nb_scanned += sscanf(argv[5], "%lu", &block_hi);                nb_scanned += sscanf(argv[6], "%lf", &rsp_backoff_window);            }            if(nb_scanned != 4) {                tcl.resultf("%s: wrong number of parameters for \"send statreq\"", name_);                return TCL_ERROR;            }            send_status_request(pass_nb, block_lo, block_hi, rsp_backoff_window);             return TCL_OK;        }    }    if(strcmp(argv[1], "start") == 0) {        if(MFTPAgent::init() == TCL_ERROR) {            return TCL_ERROR;        };        init_user_file((unsigned long) readAheadBufsize_);        return TCL_OK;    }    return Agent::command(argc, argv);}void MFTPSndAgent::recv(Packet* p, Handler* h){    hdr_ip* ih = hdr_ip::access(p);    hdr_mftp* mh = hdr_mftp::access(p);    if(ih->daddr() == 0) {        assert(false);        // Packet from local agent.    } else {        switch(mh->type) {        case hdr_mftp::PDU_DATA_TRANSFER:        case hdr_mftp::PDU_STATUS_REQUEST:            // as the sender is a member of the multicast group as well,            // it receives all data it has sent. So just ignore it.            break;        case hdr_mftp::PDU_NAK:            process_nak(mh->spec.nak, p->accessdata(), CurrentPass-1); // -1 because we have            // incremented the pass-number already in send_data.            break;        default:            assert(false);  // unknown packet type (also possible: just ignore packet rather than exit)        }        Packet::free(p);    }}void MFTPSndAgent::send_status_request(unsigned long pass_nb,                                       unsigned long block_lo,                                       unsigned long block_hi,                                       double rsp_backoff_window){    Packet* p = Agent::allocpkt();    hdr_mftp* hdr = hdr_mftp::access(p);    assert(FileDGrams > 0);                    // we need this requirement here    // initialize the header of the status request packet:    hdr->type = hdr_mftp::PDU_STATUS_REQUEST;    hdr->spec.statReq.pass_nb  = pass_nb;    hdr->spec.statReq.block_lo = block_lo;    hdr->spec.statReq.block_hi = block_hi;    hdr->spec.statReq.RspBackoffWindow = rsp_backoff_window;    // transmit packet    hdr_cmn* ch = hdr_cmn::access(p);    ch->size() = sizeof(hdr_mftp);    target_->recv(p);}// process incoming nak:void MFTPSndAgent::process_nak(hdr_mftp::Spec::Nak& nak,                                  unsigned char* nak_bitmap,                                  unsigned long currentPass){    assert(1 <= nak.nak_count && nak.nak_count <= nb_groups); // or else some receiver is fooling us.    assert(nak.pass_nb <= currentPass);  // pass greater than requested? => a receiver is fooling us.    Tcl& tcl = Tcl::instance();    tcl.evalf("%s recv nak %lu %lu %lu", name_,              (unsigned long) nak.pass_nb,              (unsigned long) nak.block_nb,              (unsigned long) nak.nak_count);    assert(dtus_per_block % 8 == 0);         // This property is required for the following    // start_group_nb corresponds to first bit of NAK-bitmap:    const unsigned long start_group_nb = dtus_per_block * nak.block_nb;    // end_group_nb corresponds to last group number of NAK-bitmap plus one    const unsigned long end_group_nb = min(nb_groups, dtus_per_block * (nak.block_nb + 1));    // get starting index into naks-array for this block    const unsigned long nak_index = start_group_nb / 8;    // number of status bytes in pdu    const unsigned long nak_bytes = (end_group_nb - start_group_nb + 7) / 8;    // pointer to location in array at which the received nak bitmap must be    // or'd to the sender-bitmap (the bitmap in which the sender collects the naks)    unsigned char* nak_array = naks + nak_index;    // if this nak pdu is from a previous pass (i.e. a delayed nak), ignore the status    // bits for dtu's that we've just retransmitted in the current pass:    if(nak.pass_nb < currentPass) {        unsigned char* retx_array = retx + nak_index;        for(unsigned long i = 0; i < nak_bytes; i++) {            if(*nak_bitmap) {                // "AND out" bits for already transmitted packets and                // "OR in" the result into newly constructed NAK bitmap                *nak_array |= (*nak_bitmap & (~*retx_array));            }                        nak_array++;            retx_array++;            nak_bitmap++;        }    }    else {        assert(nak.pass_nb == currentPass); // this nak belongs to the current pass        for(unsigned long i = 0; i < nak_bytes; i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -