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

📄 tcpapp.cc

📁 柯老师网站上找到的
💻 CC
字号:
// Copyright (c) Xerox Corporation 1998. All rights reserved.//// License is granted to copy, to use, and to make and to use derivative// works for research and evaluation purposes, provided that Xerox is// acknowledged in all documentation pertaining to any such copy or// derivative work. Xerox grants no other licenses expressed or// implied. The Xerox trade name should not be used in any advertising// without its written permission. //// XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE// MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE// FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" without// express or implied warranty of any kind.//// These notices must be retained in any copies of any part of this// software. //// $Header: /nfs/jade/vint/CVSROOT/ns-2/webcache/tcpapp.cc,v 1.14 1999/09/10 18:53:13 haoboy Exp $//// Tcp application: transmitting real application data// // Allows only one connection. Model underlying TCP connection as a // FIFO byte stream, use this to deliver user data#include "agent.h"#include "app.h"#include "tcpapp.h"// Buffer management stuff.CBuf::CBuf(AppData *c, int nbytes){	nbytes_ = nbytes;	size_ = c->size();  	if (size_ > 0) 		data_ = c;  	else   		data_ = NULL;	next_ = NULL;}CBufList::~CBufList() {	while (head_ != NULL) {		tail_ = head_;		head_ = head_->next_;		delete tail_;	}}void CBufList::insert(CBuf *cbuf) {	if (tail_ == NULL) 		head_ = tail_ = cbuf;	else {		tail_->next_ = cbuf;		tail_ = cbuf;	}#ifdef TCPAPP_DEBUG	num_++;#endif}CBuf* CBufList::detach(){	if (head_ == NULL)		return NULL;	CBuf *p = head_;	if ((head_ = head_->next_) == NULL)		tail_ = NULL;#ifdef TCPAPP_DEBUG	num_--;#endif	return p;}// ADU for plain TcpApp, which is by default a string of otcl script// XXX Local to this fileclass TcpAppString : public AppData {private:	int size_;	char* str_; public:	TcpAppString() : AppData(TCPAPP_STRING), size_(0), str_(NULL) {}	TcpAppString(TcpAppString& d) : AppData(d) {		size_ = d.size_;		if (size_ > 0) {			str_ = new char[size_];			strcpy(str_, d.str_);		} else			str_ = NULL;	}	virtual ~TcpAppString() { 		if (str_ != NULL) 			delete []str_; 	}	char* str() { return str_; }	virtual int size() const { return AppData::size() + size_; }	// Insert string-contents into the ADU	void set_string(const char* s) {		if ((s == NULL) || (*s == 0)) 			str_ = NULL, size_ = 0;		else {			size_ = strlen(s) + 1;			str_ = new char[size_];			assert(str_ != NULL);			strcpy(str_, s);		}	}	virtual AppData* copy() {		return new TcpAppString(*this);	}};// TcpAppstatic class TcpCncClass : public TclClass {public:	TcpCncClass() : TclClass("Application/TcpApp") {}	TclObject* create(int argc, const char*const* argv) {		if (argc != 5)			return NULL;		Agent *tcp = (Agent *)TclObject::lookup(argv[4]);		if (tcp == NULL) 			return NULL;		return (new TcpApp(tcp));	}} class_tcpcnc_app;TcpApp::TcpApp(Agent *tcp) : 	Application(), curdata_(0), curbytes_(0){	agent_ = tcp;	agent_->attachApp(this);}TcpApp::~TcpApp(){	// XXX Before we quit, let our agent know what we no longer exist	// so that it won't give us a call later...	agent_->attachApp(NULL);}// Send with callbacks to transfer application datavoid TcpApp::send(int nbytes, AppData *cbk){	CBuf *p = new CBuf(cbk, nbytes);#ifdef TCPAPP_DEBUG	p->time() = Scheduler::instance().clock();#endif	cbuf_.insert(p);	Application::send(nbytes);}// All we need to know is that our sink has received one messagevoid TcpApp::recv(int size){	// If it's the start of a new transmission, grab info from dest, 	// and execute callback	if (curdata_ == 0)		curdata_ = dst_->rcvr_retrieve_data();	if (curdata_ == 0) {		fprintf(stderr, "[%g] %s receives a packet but no callback!\n",			Scheduler::instance().clock(), name_);		return;	}	curbytes_ += size;#ifdef TCPAPP_DEBUG	fprintf(stderr, "[%g] %s gets data size %d, %s\n", 		Scheduler::instance().clock(), name(), curbytes_, 		curdata_->data());#endif	if (curbytes_ == curdata_->bytes()) {		// We've got exactly the data we want		// If we've received all data, execute the callback		process_data(curdata_->size(), curdata_->data());		// Then cleanup this data transmission		delete curdata_;		curdata_ = NULL;		curbytes_ = 0;	} else if (curbytes_ > curdata_->bytes()) {		// We've got more than we expected. Must contain other data.		// Continue process callbacks until the unfinished callback		while (curbytes_ >= curdata_->bytes()) {			process_data(curdata_->size(), curdata_->data());			curbytes_ -= curdata_->bytes();#ifdef TCPAPP_DEBUG			fprintf(stderr, 				"[%g] %s gets data size %d(left %d)\n", 				Scheduler::instance().clock(), 				name(),				curdata_->bytes(), curbytes_);				//curdata_->data());#endif			delete curdata_;			curdata_ = dst_->rcvr_retrieve_data();			if (curdata_ != 0)				continue;			if ((curdata_ == 0) && (curbytes_ > 0)) {				fprintf(stderr, "[%g] %s gets extra data!\n",					Scheduler::instance().clock(), name_);				// XXX Remove this before commit!!!				Tcl::instance().eval("[Test instance] flush-trace");				abort();			} else				// Get out of the look without doing a check				break;		}	}// 	else if (curbytes_ < curdata_->bytes()) {// 		fprintf(stderr, "[%g] %s gets less data than expected!!\n",// 			Scheduler::instance().clock(), name_);// 		// XXX Remove this before commit!!!// 		Tcl::instance().eval("[Test instance] flush-trace");// 		abort();// 	}}void TcpApp::resume(){	// Do nothing}int TcpApp::command(int argc, const char*const* argv){	Tcl& tcl = Tcl::instance();	if (strcmp(argv[1], "connect") == 0) {		dst_ = (TcpApp *)TclObject::lookup(argv[2]);		if (dst_ == NULL) {			tcl.resultf("%s: connected to null object.", name_);			return (TCL_ERROR);		}		dst_->connect(this);		return (TCL_OK);	} else if (strcmp(argv[1], "send") == 0) {		/*		 * <app> send <size> <tcl_script>		 */		int size = atoi(argv[2]);		if (argc == 3)			send(size, NULL);		else {			TcpAppString *tmp = new TcpAppString();			tmp->set_string(argv[3]);			send(size, tmp);		}		return (TCL_OK);	} else if (strcmp(argv[1], "dst") == 0) {		tcl.resultf("%s", dst_->name());		return TCL_OK;	}	return Application::command(argc, argv);}void TcpApp::process_data(int size, AppData* data) {	if (data == NULL)		return;	// XXX Default behavior:	// If there isn't a target, use tcl to evaluate the data	if (target())		send_data(size, data);	else if (data->type() == TCPAPP_STRING) {		TcpAppString *tmp = (TcpAppString*)data;		Tcl::instance().eval(tmp->str());	}}

⌨️ 快捷键说明

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