socket.cpp
Go to the documentation of this file.
00001 /*
00002  * Socket.cpp
00003  *
00004  *  Created on: 14.11.2008
00005  *      Author:
00006  */
00007 
00008 // Implementation of the Socket class.
00009 
00010 #include "mocap_optitrack/socket.h"
00011 #include <cstring>
00012 #include <cerrno>
00013 #include <fcntl.h>
00014 #include <iostream>
00015 #include <stdio.h>
00016 #include <sstream>
00017 
00018 #include <ros/ros.h>
00019 
00020 UdpMulticastSocket::UdpMulticastSocket( const int local_port, const std::string multicast_ip ) 
00021 {
00022   // Create a UDP socket
00023   ROS_INFO( "Creating socket..." );
00024   m_socket = socket( AF_INET, SOCK_DGRAM, 0 );
00025   if( m_socket < 0 )
00026     throw SocketException( strerror( errno ) );
00027 
00028   // Allow reuse of local addresses
00029   ROS_INFO( "Setting socket options..." );
00030   int option_value = 1;
00031   int result = setsockopt( m_socket, SOL_SOCKET, SO_REUSEADDR, (void*)&option_value, sizeof( int ) );
00032   if( result == -1 )
00033   {
00034     std::stringstream error;
00035     error << "Failed to set socket option: ";
00036     switch( errno )
00037     {
00038       case EBADF:
00039         error << "EBADF";
00040         break;
00041       case EFAULT:
00042         error << "EFAULT";
00043         break;
00044       case EINVAL:
00045         error << "EINVAL";
00046         break;
00047       case ENOPROTOOPT:
00048         error << "ENOPROTOOPT";
00049         break;
00050       case ENOTSOCK:
00051         error << "ENOTSOCK";
00052         break;
00053       default:
00054         error << "unknown error";
00055         break;
00056     }
00057     throw SocketException( error.str().c_str() );    
00058   }
00059   
00060   // Fill struct for local address
00061   memset ( &m_local_addr, 0, sizeof ( m_local_addr ) );
00062   m_local_addr.sin_family = AF_INET;
00063   m_local_addr.sin_addr.s_addr = htonl( INADDR_ANY );
00064   m_local_addr.sin_port = htons( local_port );
00065   ROS_INFO( "Local address: %s:%i", inet_ntoa( m_local_addr.sin_addr ), ntohs( m_local_addr.sin_port ) );
00066 
00067   // Bind the socket
00068   ROS_INFO( "Binding socket to local address..." );
00069   result = bind( m_socket, (sockaddr*)&m_local_addr, sizeof( m_local_addr ) );
00070   if( result == -1 )
00071   {
00072     std::stringstream error;
00073     error << "Failed to bind socket to local address:" << strerror( errno );
00074     throw SocketException( error.str().c_str() );
00075   }
00076   
00077   // Join multicast group
00078   struct ip_mreq mreq;
00079   mreq.imr_multiaddr.s_addr = inet_addr( multicast_ip.c_str() );
00080   mreq.imr_interface = m_local_addr.sin_addr;
00081   ROS_INFO( "Joining multicast group %s...", inet_ntoa( mreq.imr_multiaddr ) );
00082 
00083   result = setsockopt(m_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
00084   if( result == -1 )
00085   {
00086     std::stringstream error;
00087     error << "Failed to set socket option: ";
00088     switch( errno )
00089     {
00090       case EBADF:
00091         error << "EBADF";
00092         break;
00093       case EFAULT:
00094         error << "EFAULT";
00095         break;
00096       case EINVAL:
00097         error << "EINVAL";
00098         break;
00099       case ENOPROTOOPT:
00100         error << "ENOPROTOOPT";
00101         break;
00102       case ENOTSOCK:
00103         error << "ENOTSOCK";
00104         break;
00105       default:
00106         error << "unknown error";
00107         break;
00108     }
00109     throw SocketException( error.str().c_str() );    
00110   }
00111     
00112   // Make socket non-blocking
00113   ROS_INFO( "Enabling non-blocking I/O" );
00114   int flags = fcntl( m_socket, F_GETFL , 0 );
00115   result = fcntl(m_socket, F_SETFL, flags | O_NONBLOCK);
00116   if( result == -1 )
00117   {
00118     std::stringstream error;
00119     error << "Failed to enable non-blocking I/O: " << strerror( errno );
00120     throw SocketException( error.str().c_str() );
00121   }
00122 }
00123 
00124 UdpMulticastSocket::~UdpMulticastSocket()
00125 {
00126   close( m_socket );
00127 }
00128 
00129 int UdpMulticastSocket::recv()
00130 {
00131   memset ( buf, 0, MAXRECV + 1 );
00132 
00133   sockaddr_in remote_addr;
00134   int addr_len = sizeof(struct sockaddr);
00135   int status = recvfrom(
00136     m_socket,
00137     buf,
00138     MAXRECV,
00139     0,
00140     (sockaddr *)&remote_addr,
00141     (socklen_t*)&addr_len);
00142 
00143   if( status > 0 )
00144     ROS_INFO( "%4i bytes received from %s:%i", status, inet_ntoa( remote_addr.sin_addr ), ntohs( remote_addr.sin_port ) );
00145   else if( status == 0 )
00146     ROS_INFO( "Connection closed by peer" );
00147 
00148   return status;
00149 }


mocap_optitrack
Author(s): Kathrin Gräve/graeve@ais.uni-bonn.de, Alex Bencz/abencz@clearpathrobotics.com
autogenerated on Mon Oct 6 2014 02:22:13