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


mocap_optitrack
Author(s): Kathrin Gräve/graeve@ais.uni-bonn.de, Alex Bencz/abencz@clearpathrobotics.com
autogenerated on Tue Oct 15 2013 10:27:57