TPKTClientSocket.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:7k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const TPKTClientSocket_cxx_Version = 
  51.     "$Id: TPKTClientSocket.cxx,v 1.10 2001/06/26 22:54:22 icahoon Exp $";
  52. #include "TPKTClientSocket.hxx"
  53. #include "IPAddress.hxx"
  54. #include "TransportCommon.hxx"
  55. #include "SystemException.hxx"
  56. #include "SystemStatus.hxx"
  57. #include "VLog.hxx"
  58. #include <cerrno>
  59. using Vocal::Transport::TPKTClientSocket;
  60. using Vocal::Transport::TCPClientSocket;
  61. using Vocal::Transport::IPAddress;
  62. using Vocal::IO::file_descriptor_t;
  63. using Vocal::Logging::VLog;
  64. const u_int8_t      TPKTClientSocket::TPKT_FLAG_[2] = { 0x03, 0x00 };
  65. TPKTClientSocket::TPKTClientSocket(
  66.     const char       *   name
  67. )
  68. throw ( Vocal::SystemException )
  69.     : TCPClientSocket(name ? name : "TPKTClient"),
  70.      headerPosition_(0)
  71. {
  72.     header_[0] = header_[1] = header_[2] = header_[3] = 0;
  73. }
  74. TPKTClientSocket::TPKTClientSocket(
  75.     const IPAddress  &   localAddr,
  76.     const char       *   name
  77. )
  78. throw ( Vocal::SystemException )
  79.     :  TCPClientSocket(localAddr, (name ? name : "TPKTClient")),
  80.      headerPosition_(0)
  81. {
  82.     header_[0] = header_[1] = header_[2] = header_[3] = 0;
  83. }
  84. TPKTClientSocket::TPKTClientSocket(
  85.     const IPAddress  &   localAddr,
  86.     const IPAddress  &   remoteAddr,
  87.     const char       *   name
  88. )
  89. throw ( Vocal::SystemException, Vocal::SystemStatus )
  90.     :  TCPClientSocket(localAddr, remoteAddr, (name ? name : "TPKTClient")),
  91.      headerPosition_(0)
  92. {
  93.     header_[0] = header_[1] = header_[2] = header_[3] = 0;
  94. }
  95. TPKTClientSocket::TPKTClientSocket(
  96.     file_descriptor_t      fd,
  97.     const IPAddress  &   remoteAddr,
  98.     const char       *   name
  99. )
  100. throw ( Vocal::SystemException, Vocal::SystemStatus )
  101.     :  TCPClientSocket(fd, remoteAddr, (name ? name : "TPKTClient")),
  102.      headerPosition_(0)
  103. {
  104.     header_[0] = header_[1] = header_[2] = header_[3] = 0;
  105. }
  106. TPKTClientSocket::~TPKTClientSocket()
  107. {
  108. }
  109. int 
  110. TPKTClientSocket::send(const string & message)
  111. throw ( Vocal::SystemException, 
  112.      Vocal::SystemStatus, 
  113. Vocal::Transport::ConnectionBrokenException )
  114. {
  115.     sendTPKTHeader(message.size());
  116.     
  117.     return ( StreamClientSocket::send(message) );
  118. }
  119. int 
  120. TPKTClientSocket::send(const char * message)
  121. throw ( Vocal::SystemException, 
  122.      Vocal::SystemStatus, 
  123. Vocal::Transport::ConnectionBrokenException )
  124. {
  125.     int messageSize = ( message ? strlen(message) : 0 );
  126.     
  127.     sendTPKTHeader(messageSize);
  128.     
  129.     return ( StreamClientSocket::send(message) );
  130. }
  131. int 
  132. TPKTClientSocket::send(const vector<u_int8_t> & message)
  133. throw ( Vocal::SystemException, 
  134.      Vocal::SystemStatus, 
  135. Vocal::Transport::ConnectionBrokenException )
  136. {
  137.     sendTPKTHeader(message.size());
  138.     
  139.     return ( StreamClientSocket::send(message) );
  140. }
  141. int 
  142. TPKTClientSocket::send(const u_int8_t * message, size_t messageSize)
  143. throw ( Vocal::SystemException, 
  144.      Vocal::SystemStatus, 
  145. Vocal::Transport::ConnectionBrokenException )
  146. {
  147.     sendTPKTHeader(messageSize);
  148.     
  149.     return ( StreamClientSocket::send(message, messageSize) );
  150. }
  151. u_int16_t 
  152. TPKTClientSocket::receiveTPKTHeader()
  153. throw ( Vocal::SystemException, 
  154.      Vocal::SystemStatus, 
  155. Vocal::Transport::ConnectionBrokenException )
  156. {
  157.     const string    fn("TPKTClientSocket::receiveTPKTHeader");
  158.     VLog         log(fn);
  159.     u_int8_t *   bytes    = &header_[headerPosition_];
  160.     int          bytesLeft  = 4 - headerPosition_;
  161.     
  162.     headerPosition_ += StreamClientSocket::receive(bytes, bytesLeft);
  163.     if ( headerPosition_ < 4 )
  164.     {
  165.      throw Vocal::SystemStatus(fn + " parital TPKT header received.",
  166.                __FILE__, __LINE__, EAGAIN);
  167.     }
  168.     if ( header_[0] != TPKT_FLAG_[0] || header_[1] != TPKT_FLAG_[1] )
  169.     {
  170.      VDEBUG(log) << fn << ": TPKT header/reserved version incorrect."
  171.         << VDEBUG_END(log);
  172.     }
  173.     
  174.     u_int16_t     length = ntohs(*(u_int16_t *)(&header_[2]));
  175.     length = (length < 4 ? 0 : length - 4);
  176.     clearTPKTHeader();
  177.     
  178.     VDEBUG(log) << fn << ": remaining length = " << length << VDEBUG_END(log);
  179.     
  180.     return ( length );
  181. }
  182. void
  183. TPKTClientSocket::clearTPKTHeader()
  184. {
  185.     header_[0] = header_[1] = header_[2] = header_[3] = 0;
  186.     headerPosition_ = 0;
  187. }
  188. void     
  189. TPKTClientSocket::sendTPKTHeader(u_int16_t  size)
  190. throw ( Vocal::SystemException, 
  191.      Vocal::SystemStatus, 
  192. Vocal::Transport::ConnectionBrokenException )
  193. {
  194.     const string    fn("TPKTClientSocket::sendTPKTHeader");
  195.     VLog         log(fn);
  196.     // Include the TPKT header in the size.
  197.     //
  198.     size += 4;
  199.     
  200.     VDEBUG(log) << "TPKT size: " << size << VDEBUG_END(log);
  201.     
  202.     u_int8_t     header[4];
  203.     u_int16_t *   length = (u_int16_t *)&header[2];
  204.     
  205.     header[0] = TPKT_FLAG_[0];
  206.     header[1] = TPKT_FLAG_[1];
  207.     *length = htons(size);
  208.     
  209.     StreamClientSocket::send(header, 4);
  210. }