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

流媒体/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 DatagramSocket_cxx_Version = 
  51.     "$Id: DatagramSocket.cxx,v 1.21 2001/06/26 22:54:22 icahoon Exp $";
  52. #include "DatagramSocket.hxx"
  53. #include "TransportCommon.hxx"
  54. #include "SystemException.hxx"
  55. #include "SystemStatus.hxx"
  56. #include "VLog.hxx"
  57. #include <cerrno>
  58. #include <sys/types.h>
  59. using Vocal::Transport::DatagramSocket;
  60. using Vocal::Transport::Socket;
  61. using Vocal::Transport::TransportAddress;
  62. using Vocal::Transport::AddressFamily;
  63. using Vocal::Transport::SocketType;
  64. using Vocal::Logging::VLog;
  65. DatagramSocket::DatagramSocket(
  66.     const AddressFamily      &   addressFamily,
  67.     const char            *   name
  68. )
  69. throw ( Vocal::SystemException )
  70.     :  Socket( addressFamily, 
  71.           SocketType(SOCK_DGRAM), 
  72. (name ? name : "Datagram")),
  73.      remoteAddr_(0),
  74. localAddrUpdated_(false)
  75. {
  76. }
  77. DatagramSocket::DatagramSocket(
  78.     const TransportAddress   &   localAddr,
  79.     const char            *   name
  80. )
  81. throw ( Vocal::SystemException )
  82.     :  Socket(localAddr, 
  83.           SocketType(SOCK_DGRAM), 
  84. (name ? name : "Datagram")),
  85.      remoteAddr_(0),
  86. localAddrUpdated_(false)
  87. {
  88. }
  89. DatagramSocket::DatagramSocket(
  90.     const TransportAddress   &   localAddr,
  91.     const TransportAddress   &   remoteAddr,
  92.     const char            *   name
  93. )
  94.     throw ( Vocal::SystemException )
  95.     :  Socket(localAddr, 
  96.           SocketType(SOCK_DGRAM), 
  97. (name ? name : "Datagram")),
  98.      remoteAddr_(0),
  99. localAddrUpdated_(false)
  100. {
  101.     connect(remoteAddr);
  102. }
  103. DatagramSocket::~DatagramSocket()
  104. {
  105. }
  106. void
  107. DatagramSocket::connect(
  108.     const TransportAddress  &  remoteAddr
  109. )
  110. throw ( Vocal::SystemException )
  111. {
  112.     const string    fn("DatagramSocket::connect");
  113.     VLog         log(fn);
  114.     
  115.     if ( remoteAddr_ == 0 )
  116.     {
  117.         remoteAddr_ = remoteAddr.clone();
  118.     }
  119.     
  120.     if (   ::connect(fd_, 
  121.                remoteAddr_->getAddress(), 
  122.      remoteAddr_->getAddressLength()) < SUCCESS
  123. )
  124.     {
  125.      throw Vocal::SystemException(fn + " on connect(): " + strerror(errno), 
  126.                __FILE__, __LINE__, errno);
  127.     }
  128.     VDEBUG(log) << fn << ": fd = " << fd_ 
  129.           << " connected to remote address = "
  130. << *remoteAddr_ << VDEBUG_END(log);
  131. }    
  132. void
  133. DatagramSocket::disconnect()
  134. throw ( Vocal::SystemException )
  135. {
  136.     const string    fn("DatagramSocket::disconnect");
  137.     VLog         log(fn);
  138.     if ( !remoteAddr_ )
  139.     {
  140.      return;
  141.     }
  142.     
  143.     sockaddr sa;
  144.     sa.sa_family = AF_UNSPEC;
  145.     
  146.     if ( ::connect(fd_, &sa, sizeof(sa)) )
  147.     {
  148.      throw Vocal::SystemException(fn + " on disconnect(): " + strerror(errno), 
  149.                __FILE__, __LINE__, errno);
  150.     }
  151.     VDEBUG(log) << fn << ": fd = " << fd_ 
  152.           << " disconnected from remote address = "
  153. << *remoteAddr_ << VDEBUG_END(log);
  154.     remoteAddr_ = 0;
  155. }
  156.     
  157. int 
  158. DatagramSocket::send(const string & message)
  159. throw ( Vocal::SystemException, Vocal::SystemStatus )
  160. {
  161.     if ( !remoteAddr_ || message.size() == 0 )
  162.     {
  163.      return ( 0 );
  164.     }
  165.     void * msg = reinterpret_cast<void *>(const_cast<char *>(message.c_str()));
  166.     
  167.     return ( sendMessage(msg, message.size(), 0) );
  168. }
  169. int 
  170. DatagramSocket::send(const char * message)
  171. throw ( Vocal::SystemException, Vocal::SystemStatus )
  172. {
  173.     size_t  messageLength = ( message ? strlen(message) : 0 );
  174.     
  175.     if ( !remoteAddr_ || messageLength == 0 )
  176.     {
  177.      return ( 0 );
  178.     }
  179.     void * msg = reinterpret_cast<void *>(const_cast<char *>(message));
  180.     
  181.     return ( sendMessage(msg, messageLength, 0) );
  182. }
  183. int 
  184. DatagramSocket::send(const vector<u_int8_t> & message)
  185. throw ( Vocal::SystemException, Vocal::SystemStatus )
  186. {
  187.     if ( !remoteAddr_ || message.size() == 0 )
  188.     {
  189.      return ( 0 );
  190.     }
  191.     void * msg = reinterpret_cast<void *>(const_cast<u_int8_t *>(&message[0]));
  192.     return ( sendMessage(msg, message.size(), 0) );
  193. }
  194. int 
  195. DatagramSocket::send(const u_int8_t * message, size_t messageLength)
  196. throw ( Vocal::SystemException, Vocal::SystemStatus )
  197. {
  198.     if ( !remoteAddr_ || message == 0 || messageLength == 0 )
  199.     {
  200.      return ( 0 );
  201.     }
  202.     void * msg = reinterpret_cast<void *>(const_cast<u_int8_t *>(message));
  203.     return ( sendMessage(msg, messageLength, 0) );
  204. }
  205. int 
  206. DatagramSocket::sendTo(
  207.     const string         &  message, 
  208.     const TransportAddress  & remoteAddress
  209. )
  210. throw ( Vocal::SystemException, Vocal::SystemStatus )
  211. {
  212.     if ( message.size() == 0 )
  213.     {
  214.      return ( 0 );
  215.     }
  216.     void * msg = reinterpret_cast<void *>(const_cast<char *>(message.c_str()));
  217.     return ( sendMessage(msg, message.size(), &remoteAddress) );
  218. }
  219. int 
  220. DatagramSocket::sendTo(
  221.     const char         *  message, 
  222.     const TransportAddress  & remoteAddress
  223. )
  224. throw ( Vocal::SystemException, Vocal::SystemStatus )
  225. {
  226.     size_t messageLength = ( message ? strlen(message) : 0 );
  227.     
  228.     if ( messageLength == 0 )
  229.     {
  230.      return ( 0 );
  231.     }
  232.     void * msg = reinterpret_cast<void *>(const_cast<char *>(message));
  233.     return ( sendMessage(msg, messageLength, &remoteAddress) );
  234. }
  235. int 
  236. DatagramSocket::sendTo( 
  237.     const vector<u_int8_t>  &  message,
  238.     const TransportAddress  & remoteAddress
  239. )
  240. throw ( Vocal::SystemException, Vocal::SystemStatus )
  241. {
  242.     if ( message.size() == 0 )
  243.     {
  244.      return ( 0 );
  245.     }
  246.     void * msg = reinterpret_cast<void *>(const_cast<u_int8_t *>(&message[0]));
  247.     return ( sendMessage(msg, message.size(), &remoteAddress) );
  248. }
  249. int 
  250. DatagramSocket::sendTo( 
  251.     const u_int8_t       *  message,
  252.     size_t             messageLength,
  253.     const TransportAddress  & remoteAddress
  254. )
  255. throw ( Vocal::SystemException, Vocal::SystemStatus )
  256. {
  257.     if ( message == 0 || messageLength == 0 )
  258.     {
  259.      return ( 0 );
  260.     }
  261.     void * msg = reinterpret_cast<void *>(const_cast<u_int8_t *>(message));
  262.     return ( sendMessage(msg, messageLength, &remoteAddress) );
  263. }
  264. int 
  265. DatagramSocket::receive(string & message)
  266. throw ( Vocal::SystemException, Vocal::SystemStatus )
  267. {
  268.     if ( !remoteAddr_ )
  269.     {
  270.      return ( 0 );
  271.     }
  272.     
  273.     void * msg = reinterpret_cast<void *>(const_cast<char *>(message.data()));
  274.     int bytesReceived = recvMessage(msg, message.size(), 0);
  275.     message.resize(bytesReceived);
  276.     
  277.     return ( bytesReceived );
  278. }
  279. int 
  280. DatagramSocket::receive(char * message, size_t messageCapacity)
  281. throw ( Vocal::SystemException, Vocal::SystemStatus )
  282. {
  283.     if ( !remoteAddr_ || message == 0 || messageCapacity == 0 )
  284.     {
  285.      return ( 0 );
  286.     }
  287.     
  288.     void * msg = reinterpret_cast<void *>(message);
  289.     int bytesReceived = recvMessage(msg, (messageCapacity > 1 ? messageCapacity-1 : 1 ), 0);
  290.     
  291.     if ( messageCapacity > 1 )
  292.     {
  293.      message[bytesReceived] = '';
  294.     }
  295.     return ( bytesReceived );
  296. }
  297. int 
  298. DatagramSocket::receive(vector<u_int8_t> & message)
  299. throw ( Vocal::SystemException, Vocal::SystemStatus )
  300. {
  301.     if ( !remoteAddr_ )
  302.     {
  303.      return ( 0 );
  304.     }
  305.     
  306.     message.clear();
  307.     
  308.     void * msg = reinterpret_cast<void *>(&message[0]);
  309.     int bytesReceived = recvMessage(msg, message.size(), 0);
  310.     return ( bytesReceived );
  311. }
  312. int 
  313. DatagramSocket::receive(u_int8_t * message, size_t messageCapacity)
  314. throw ( Vocal::SystemException, Vocal::SystemStatus )
  315. {
  316.     if ( !remoteAddr_ || message == 0 || messageCapacity == 0 )
  317.     {
  318.      return ( 0 );
  319.     }
  320.     
  321.     void * msg = reinterpret_cast<void *>(message);
  322.     int bytesReceived = recvMessage(msg, messageCapacity, 0);
  323.     
  324.     return ( bytesReceived );
  325. }
  326. int 
  327. DatagramSocket::receiveFrom(
  328.     string            & message, 
  329.     TransportAddress       & remoteAddress
  330. )
  331. throw ( Vocal::SystemException, Vocal::SystemStatus )
  332. {
  333.     void * msg = reinterpret_cast<void *>(const_cast<char *>(message.data()));
  334.    
  335.     int bytesReceived = recvMessage(msg, message.size(), &remoteAddress);
  336.     message.resize(bytesReceived);
  337.     
  338.     return ( bytesReceived );
  339. }
  340. int 
  341. DatagramSocket::receiveFrom(
  342.     char            * message, 
  343.     size_t              messageCapacity,
  344.     TransportAddress       & remoteAddress
  345. )
  346. throw ( Vocal::SystemException, Vocal::SystemStatus )
  347. {
  348.     if ( message == 0 || messageCapacity == 0 )
  349.     {
  350.      return ( 0 );
  351.     }
  352.     
  353.     void * msg = reinterpret_cast<void *>(message);
  354.    
  355.     int bytesReceived = recvMessage(msg, (messageCapacity > 1 ? messageCapacity-1 : 1 ), &remoteAddress);
  356.     if ( messageCapacity > 1 )
  357.     {    
  358.      message[bytesReceived] = '';
  359.     }
  360.     
  361.     return ( bytesReceived );
  362. }
  363. int 
  364. DatagramSocket::receiveFrom( 
  365.     vector<u_int8_t>      & message,
  366.     TransportAddress       & remoteAddress
  367. )
  368. throw ( Vocal::SystemException, Vocal::SystemStatus )
  369. {
  370.     message.clear();
  371.     
  372.     void * msg = reinterpret_cast<void *>(&message[0]);
  373.    
  374.     int bytesReceived = recvMessage(msg, message.size(), &remoteAddress);
  375.     message.resize(bytesReceived);
  376.     
  377.     return ( bytesReceived );
  378. }
  379. int 
  380. DatagramSocket::receiveFrom( 
  381.     u_int8_t       * message,
  382.     size_t             messageCapacity,
  383.     TransportAddress       & remoteAddress
  384. )
  385. throw ( Vocal::SystemException, Vocal::SystemStatus )
  386. {
  387.     if ( message == 0 || messageCapacity == 0 )
  388.     {
  389.      return ( 0 );
  390.     }
  391.     
  392.     void * msg = reinterpret_cast<void *>(message);
  393.    
  394.     return ( recvMessage(msg, messageCapacity, &remoteAddress) );
  395. }
  396. Sptr<TransportAddress>
  397. DatagramSocket::getRemoteAddress() const
  398. {
  399.     return ( remoteAddr_ );
  400. }
  401. ostream &           
  402. DatagramSocket::writeTo(ostream & out) const
  403. {
  404.     Socket::writeTo(out);
  405.     
  406.     if ( remoteAddr_ != 0 )
  407.     {
  408.      out << ", remote = " << *remoteAddr_;
  409.     }
  410.     return ( out );
  411. }
  412. int
  413. DatagramSocket::sendMessage(
  414.     void              *  message, 
  415.     int                messageLength, 
  416.     const TransportAddress  * addr
  417. )
  418. throw ( Vocal::SystemException, Vocal::SystemStatus )
  419. {
  420.     const string    fn("DatagramSocket::send");
  421.     VLog         log(fn);
  422.     int bytesSent = 0;
  423.     
  424.     if ( addr )
  425.     {
  426.      bytesSent = ::sendto( fd_, 
  427.                message, 
  428. messageLength, 
  429. 0, 
  430.                addr->getAddress(), 
  431. addr->getAddressLength());
  432.     }
  433.     else
  434.     {
  435.      bytesSent = ::send( fd_, 
  436.                  message, 
  437.        messageLength, 0);
  438.     }
  439.     
  440.     if ( bytesSent < SUCCESS )
  441.     {
  442.      int error = errno;
  443.      // If the socket is set nonblocking, we can get an EAGAIN
  444. // here, without sending the packet. If the socket is set 
  445. // blocking we can get an EINTR here, without sending the packet.
  446. // 
  447. if ( error == EAGAIN || error == EINTR )
  448. {
  449.          throw Vocal::SystemStatus(fn + " on send(): " + strerror(error),
  450.                __FILE__, __LINE__, error);
  451.      }
  452.      throw Vocal::SystemException(fn + " on send(): " + strerror(error), 
  453.                __FILE__, __LINE__, error);
  454.     }
  455.     totalBytesSent_ += bytesSent;
  456.     
  457.     VDEBUG(log) << fn << ": send on " << *this
  458. << ", bytes sent: " << bytesSent
  459. << ", of total: " << messageLength
  460. << VDEBUG_END(log);
  461.     return ( bytesSent );
  462. }
  463. int 
  464. DatagramSocket::recvMessage(
  465.     void              * message,
  466.     int                messageCapacity,
  467.     TransportAddress     * addr
  468. )
  469. throw ( Vocal::SystemException, Vocal::SystemStatus )
  470. {
  471.     const string    fn("DatagramSocket::receive");
  472.     VLog         log(fn);
  473.     int bytesReceived = 0;
  474.     if ( addr )
  475.     {
  476.      AddressFamily     af = addr->getAddressFamily();
  477. socklen_t        addrLength = addr->getAddressLength();
  478.      bytesReceived = ::recvfrom( fd_, 
  479.                     message, 
  480. messageCapacity, 
  481. 0, 
  482.                     addr->getAddress(), 
  483. &addrLength);
  484.      // They gave us the wrong type of address. duh.
  485. //
  486. if ( af != addr->getAddressFamily() )
  487. {
  488.             throw Vocal::SystemException(fn + " on recvfrom(): incorrect address type", 
  489.                __FILE__, __LINE__);
  490. }
  491.     }
  492.     else
  493.     {
  494.      bytesReceived = ::recvfrom( fd_, 
  495.                     message, 
  496. messageCapacity, 
  497. 0,
  498.                     0, 
  499. 0);
  500.     }
  501.     if ( bytesReceived < SUCCESS )
  502.     {
  503.      int error = errno;
  504.      // If the socket is set nonblocking, we can get an EAGAIN
  505. // here, without receiving the packet. If the socket is set 
  506. // blocking we can get an EINTR here, without receiving the packet.
  507. // 
  508. if ( error == EAGAIN || error == EINTR )
  509. {
  510.          throw Vocal::SystemStatus(fn + " on recv(): " + strerror(error),
  511.                __FILE__, __LINE__, error);
  512.      }
  513.      throw Vocal::SystemException(fn + " on recv(): " + strerror(error), 
  514.                __FILE__, __LINE__, error);
  515.     }
  516.     if ( !localAddrUpdated_ )
  517.     {
  518.      localAddrUpdated_ = true;
  519.      localAddr_->updateAddress(*this);
  520.     }
  521.         
  522.     totalBytesReceived_ += bytesReceived;
  523.     VDEBUG(log) << fn << ": received on " << *this
  524. << ", bytes received: " << bytesReceived
  525. << ", of capacity: " << messageCapacity
  526. << VDEBUG_END(log);
  527.     return ( bytesReceived );
  528. }