udp.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:5k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (C) Xerox Corporation 1997. All rights reserved.
  4.  *  
  5.  * This program is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2 of the License, or (at your
  8.  * option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18.  *
  19.  * Linking this file statically or dynamically with other modules is making
  20.  * a combined work based on this file.  Thus, the terms and conditions of
  21.  * the GNU General Public License cover the whole combination.
  22.  *
  23.  * In addition, as a special exception, the copyright holders of this file
  24.  * give you permission to combine this file with free software programs or
  25.  * libraries that are released under the GNU LGPL and with code included in
  26.  * the standard release of ns-2 under the Apache 2.0 license or under
  27.  * otherwise-compatible licenses with advertising requirements (or modified
  28.  * versions of such code, with unchanged license).  You may copy and
  29.  * distribute such a system following the terms of the GNU GPL for this
  30.  * file and the licenses of the other code concerned, provided that you
  31.  * include the source code of that other code when and as the GNU GPL
  32.  * requires distribution of source code.
  33.  *
  34.  * Note that people who make modified versions of this file are not
  35.  * obligated to grant this special exception for their modified versions;
  36.  * it is their choice whether to do so.  The GNU General Public License
  37.  * gives permission to release a modified version without this exception;
  38.  * this exception also makes it possible to release a modified version
  39.  * which carries forward this exception.
  40.  */
  41. #ifndef lint
  42. static const char rcsid[] =
  43.     "@(#) $Header: /cvsroot/nsnam/ns-2/apps/udp.cc,v 1.21 2005/08/26 05:05:28 tomh Exp $ (Xerox)";
  44. #endif
  45. #include "udp.h"
  46. #include "rtp.h"
  47. #include "random.h"
  48. #include "address.h"
  49. #include "ip.h"
  50. static class UdpAgentClass : public TclClass {
  51. public:
  52. UdpAgentClass() : TclClass("Agent/UDP") {}
  53. TclObject* create(int, const char*const*) {
  54. return (new UdpAgent());
  55. }
  56. } class_udp_agent;
  57. UdpAgent::UdpAgent() : Agent(PT_UDP), seqno_(-1)
  58. {
  59. bind("packetSize_", &size_);
  60. }
  61. UdpAgent::UdpAgent(packet_t type) : Agent(type)
  62. {
  63. bind("packetSize_", &size_);
  64. }
  65. // put in timestamp and sequence number, even though UDP doesn't usually 
  66. // have one.
  67. void UdpAgent::sendmsg(int nbytes, AppData* data, const char* flags)
  68. {
  69. Packet *p;
  70. int n;
  71. assert (size_ > 0);
  72. n = nbytes / size_;
  73. if (nbytes == -1) {
  74. printf("Error:  sendmsg() for UDP should not be -1n");
  75. return;
  76. }
  77. // If they are sending data, then it must fit within a single packet.
  78. if (data && nbytes > size_) {
  79. printf("Error: data greater than maximum UDP packet sizen");
  80. return;
  81. }
  82. double local_time = Scheduler::instance().clock();
  83. while (n-- > 0) {
  84. p = allocpkt();
  85. hdr_cmn::access(p)->size() = size_;
  86. hdr_rtp* rh = hdr_rtp::access(p);
  87. rh->flags() = 0;
  88. rh->seqno() = ++seqno_;
  89. hdr_cmn::access(p)->timestamp() = 
  90.     (u_int32_t)(SAMPLERATE*local_time);
  91. // add "beginning of talkspurt" labels (tcl/ex/test-rcvr.tcl)
  92. if (flags && (0 ==strcmp(flags, "NEW_BURST")))
  93. rh->flags() |= RTP_M;
  94. p->setdata(data);
  95. target_->recv(p);
  96. }
  97. n = nbytes % size_;
  98. if (n > 0) {
  99. p = allocpkt();
  100. hdr_cmn::access(p)->size() = n;
  101. hdr_rtp* rh = hdr_rtp::access(p);
  102. rh->flags() = 0;
  103. rh->seqno() = ++seqno_;
  104. hdr_cmn::access(p)->timestamp() = 
  105.     (u_int32_t)(SAMPLERATE*local_time);
  106. // add "beginning of talkspurt" labels (tcl/ex/test-rcvr.tcl)
  107. if (flags && (0 == strcmp(flags, "NEW_BURST")))
  108. rh->flags() |= RTP_M;
  109. p->setdata(data);
  110. target_->recv(p);
  111. }
  112. idle();
  113. }
  114. void UdpAgent::recv(Packet* pkt, Handler*)
  115. {
  116. if (app_ ) {
  117. // If an application is attached, pass the data to the app
  118. hdr_cmn* h = hdr_cmn::access(pkt);
  119. app_->process_data(h->size(), pkt->userdata());
  120. } else if (pkt->userdata() && pkt->userdata()->type() == PACKET_DATA) {
  121. // otherwise if it's just PacketData, pass it to Tcl
  122. //
  123. // Note that a Tcl procedure Agent/Udp recv {from data}
  124. // needs to be defined.  For example,
  125. //
  126. // Agent/Udp instproc recv {from data} {puts data}
  127. PacketData* data = (PacketData*)pkt->userdata();
  128. hdr_ip* iph = hdr_ip::access(pkt);
  129.                 Tcl& tcl = Tcl::instance();
  130. tcl.evalf("%s process_data %d {%s}", name(),
  131.           iph->src_.addr_ >> Address::instance().NodeShift_[1],
  132.   data->data());
  133. }
  134. Packet::free(pkt);
  135. }
  136. int UdpAgent::command(int argc, const char*const* argv)
  137. {
  138. if (argc == 4) {
  139. if (strcmp(argv[1], "send") == 0) {
  140. PacketData* data = new PacketData(1 + strlen(argv[3]));
  141. strcpy((char*)data->data(), argv[3]);
  142. sendmsg(atoi(argv[2]), data);
  143. return (TCL_OK);
  144. }
  145. } else if (argc == 5) {
  146. if (strcmp(argv[1], "sendmsg") == 0) {
  147. PacketData* data = new PacketData(1 + strlen(argv[3]));
  148. strcpy((char*)data->data(), argv[3]);
  149. sendmsg(atoi(argv[2]), data, argv[4]);
  150. return (TCL_OK);
  151. }
  152. }
  153. return (Agent::command(argc, argv));
  154. }