InPortTcpSockConsumer.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00020 #ifndef InPortTcpSockConsumer_h
00021 #define InPortTcpSockConsumer_h
00022 
00023 #include <rtm/BufferBase.h>
00024 #include <rtm/InPortConsumer.h>
00025 #include <rtm/StringUtil.h>
00026 #include <ace/INET_Addr.h>
00027 #include <ace/SOCK_Stream.h>
00028 #include <ace/SOCK_Connector.h>
00029 #include <ace/Log_Msg.h>
00030 #include <ace/OS.h>
00031 #include <iostream>
00032 
00033 namespace RTC
00034 {
00062   template <class DataType>
00063   class InPortTcpSockConsumer
00064     : public InPortConsumer
00065   {
00066   public:
00086     InPortTcpSockConsumer(BufferBase<DataType>& buffer, Properties& prop)
00087       : m_buffer(buffer), m_prop(prop), m_byteswap(true)
00088     {
00089       m_byteswap = toBool(m_prop["byteswap"], "YES", "NO", true);
00090     }
00091     
00109     InPortTcpSockConsumer(const InPortTcpSockConsumer<DataType>& consumer)
00110       : m_buffer(consumer.m_buffer), m_prop(consumer.m_prop),
00111         m_byteswap(consumer.m_byteswap), m_stream(consumer.m_stream),
00112         m_addr(consumer.m_addr) 
00113     {
00114     }
00115     
00137     InPortTcpSockConsumer&
00138     operator=(const InPortTcpSockConsumer<DataType>& consumer)
00139     {
00140       m_buffer = consumer.m_buffer;
00141       m_prop   = consumer.m_prop;
00142       m_stream = consumer.m_stream;
00143       m_addr   = consumer.m_addr;
00144       m_byteswap = consumer.m_byteswap;
00145     }
00146     
00160     virtual ~InPortTcpSockConsumer(void)
00161     {}
00162     
00176     void push()
00177     {
00178       // read data from buffer
00179       DataType data;
00180       m_buffer.read(data);
00181       std::cout << "byteswap: " << m_byteswap << std::endl;
00182       
00183       CORBA::ULong size(0);
00184       cdrMemoryStream cdrData;
00185       cdrData.setByteSwapFlag(m_byteswap);
00186       size >>= cdrData;
00187       data >>= cdrData;
00188       
00189       cdrMemoryStream cdrSize;
00190       size = cdrData.bufSize();
00191       cdrSize.setByteSwapFlag(m_byteswap);
00192       size >>= cdrSize;
00193       
00194       // hmm... type-unsafe way.
00195       memcpy(cdrData.bufPtr(), cdrSize.bufPtr(), sizeof(CORBA::ULong));
00196       
00197       int send(0);
00198       send = m_stream->send_n(cdrData.bufPtr(), size);
00199       
00200       if (send != (int)size)
00201         {
00202           std::cout << "data size: " << size << std::endl;
00203           std::cout << "send size: " << send << std::endl;
00204           std::cout << "invalid send" << std::endl;
00205         }
00206     }
00207     
00225     virtual InPortTcpSockConsumer* clone() const
00226     {
00227       return new InPortTcpSockConsumer<DataType>(*this);
00228     }
00229     
00252     virtual bool subscribeInterface(const SDOPackage::NVList& properties)
00253     {
00254       if (!NVUtil::isStringValue(properties,
00255                                  "dataport.dataflow_type",
00256                                  "Push"))
00257         {
00258           return false;
00259         }
00260       
00261       CORBA::Long index;
00262       index = NVUtil::find_index(properties,
00263                                  "dataport.tcp_any.inport_addr");
00264       if (index < 0)
00265         {
00266           return false;
00267         }
00268       
00269       const char* inport_addr;
00270       if (!(properties[index].value >>= inport_addr))
00271         {
00272           return false;
00273         }
00274       
00275       std::vector<std::string> addr(split(inport_addr, ":"));
00276       
00277       if (addr.size() != 2)
00278         {
00279           return false;
00280         }
00281       
00282       m_addr.set(addr[1].c_str(), addr[0].c_str());
00283       std::cout << "addr: " << addr[0].c_str() << std::endl;
00284       std::cout << "port: " << addr[1].c_str() << std::endl;
00285       m_stream = new ACE_SOCK_Stream();
00286       if (m_connector.connect(*m_stream, m_addr) == -1)
00287         {
00288           std::cout << "Connection failed." << std::endl;
00289           return false;
00290         }
00291       
00292       // Disable Nagle's algorithm for small packaets
00293       int flag(1);
00294       m_stream->set_option(IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
00295       
00296       return true;
00297     }
00298     
00312     virtual void unsubscribeInterface(const SDOPackage::NVList& properties)
00313     {
00314       std::cout << "unsubscribe" << std::endl;
00315       m_stream->close();
00316     }
00317     
00318   private:
00319     BufferBase<DataType>& m_buffer;
00320     Properties& m_prop;
00321     bool m_byteswap;
00322     
00323     ACE_SOCK_Stream* m_stream;
00324     ACE_SOCK_Connector m_connector;
00325     ACE_INET_Addr m_addr;
00326   };
00327 };     // namespace RTC
00328 #endif // InPortTcpSockConsumer_h

Generated on Sun May 24 14:08:45 2009 for OpenRTM by  doxygen 1.5.3