⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.cpp

📁 2009 ROBOCUP 仿真2DSERVER 源码
💻 CPP
字号:
// -*-c++-*-/***************************************************************************                          client.cpp  -  A basic client that connects to                          the server                             -------------------    begin                : 27-DEC-2001    copyright            : (C) 2001 by The RoboCup Soccer Server                           Maintenance Group.    email                : sserver-admin@lists.sourceforge.net***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU LGPL as published by the Free Software  * *   Foundation; either version 2 of the License, or (at your option) any  * *   later version.                                                        * *                                                                         * ***************************************************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "compress.h"#include <rcssbase/net/socketstreambuf.hpp>#include <rcssbase/net/udpsocket.hpp>#include <rcssbase/gzip/gzstream.hpp>#ifdef HAVE_SSTREAM#include <sstream>#else#include <strstream>#endif#include <iostream>#include <cerrno>#include <csignal>#include <cstdio>#include <cstdlib>#include <cstring>#ifndef WIN32#include <unistd.h> // select()#include <sys/select.h> // select()#include <sys/time.h> // select()#include <sys/types.h> // select()#else#include <winsock2.h>#endifclass Client {private:    rcss::net::Addr M_dest;    rcss::net::UDPSocket M_socket;    rcss::net::SocketStreamBuf * M_socket_buf;    rcss::gz::gzstreambuf * M_gz_buf;    std::ostream * M_transport;    int M_comp_level;    bool M_clean_cycle;#ifdef HAVE_LIBZ    Decompressor M_decomp;#endif    Client();    Client( const Client & );    Client & operator=( const Client & );public:    Client( const std::string & server,            const int port )        : M_dest( port ),          M_socket(),          M_socket_buf( NULL ),          M_gz_buf( NULL ),          M_transport( NULL ),          M_comp_level( -1 ),          M_clean_cycle( true )      {          M_dest.setHost( server );          open();          bind();          M_socket_buf->setEndPoint( M_dest );      }    virtual    ~Client()      {          close();      }    void run()      {          messageLoop();      }private:    int open()      {          if ( M_socket.open() )          {              if ( M_socket.setNonBlocking() < 0 )              {                  std::cerr << __FILE__ << ": " << __LINE__                      << ": Error setting socket non-blocking: "                            << strerror( errno ) << std::endl;                  M_socket.close();                  return -1;              }          }          else          {              std::cerr << __FILE__ << ": " << __LINE__                        << ": Error opening socket: "                        << strerror( errno ) << std::endl;              M_socket.close();              return -1;          }          M_socket_buf = new rcss::net::SocketStreamBuf( M_socket );          M_transport = new std::ostream( M_socket_buf );          return 0;      }    bool bind()      {          if ( ! M_socket.bind( rcss::net::Addr() ) )          {              std::cerr << __FILE__ << ": " << __LINE__                        << ": Error connecting socket" << std::endl;              M_socket.close();              return false;          }          return true;      }    void close()      {          M_socket.close();          if ( M_transport )          {              delete M_transport;              M_transport = NULL;          }          if ( M_gz_buf )          {              delete M_gz_buf;              M_gz_buf = NULL;          }          if ( M_socket_buf )          {              delete M_socket_buf;              M_socket_buf = NULL;          }      }    int setCompression( int level )      {#ifdef HAVE_LIBZ          if ( level >= 0 )          {              if ( ! M_gz_buf )              {                  M_gz_buf = new rcss::gz::gzstreambuf( *M_socket_buf );              }              M_gz_buf->setLevel( level );              M_transport->rdbuf( M_gz_buf );          }          else          {              M_transport->rdbuf( M_socket_buf );          }          return M_comp_level = level;#endif          return M_comp_level = -1;      }    void processMsg( const char * msg,                     const size_t len )      {#ifdef HAVE_LIBZ          if ( M_comp_level >= 0 )          {              M_decomp.decompress( msg, len, Z_SYNC_FLUSH );              char * out;              int size;              M_decomp.getOutput( out, size );              if ( size > 0 )              {                  parseMsg( out, size );              }          }          else#endif          {              parseMsg( msg, len );          }      }    void parseMsg( const char * msg,                   const size_t len )      {          if ( ! std::strncmp( msg, "(ok compression", 15 ) )          {              int level;              if ( std::sscanf( msg, "(ok compression %d)", &level ) == 1 )              {                  setCompression( level );              }          }          else if ( ! std::strncmp( msg, "(sense_body", 11 )                    || ! std::strncmp( msg, "(see_global", 11 )                    || ! std::strncmp( msg, "(init", 5 ) )          {              M_clean_cycle = true;          }          std::cout << std::string( msg, len - 1 ) << std::endl;      }    void messageLoop()      {          fd_set read_fds;          fd_set read_fds_back;          char buf[8192];          std::memset( &buf, 0, sizeof( char ) * 8192 );          int in = fileno( stdin );          FD_ZERO( &read_fds );          FD_SET( in, &read_fds );          FD_SET( M_socket.getFD(), &read_fds );          read_fds_back = read_fds;#ifdef WIN32          int max_fd = 0;#else          int max_fd = M_socket.getFD() + 1;#endif          while ( 1 )          {              read_fds = read_fds_back;              int ret = ::select( max_fd, &read_fds, NULL, NULL, NULL );              if ( ret < 0 )              {                  perror( "Error selecting input" );                  break;              }              else if ( ret != 0 )              {                  // read from stdin                  if ( FD_ISSET( in, &read_fds ) )                  {                      std::fgets( buf, sizeof( buf ), stdin );                      size_t len = std::strlen( buf );                      if ( len > 1 )                      {                          if ( buf[len-1] == '\n' )                          {                              buf[len-1] = '\0';                              --len;                          }                          M_transport->write( buf, len + 1 );                          M_transport->flush();                          if ( ! M_transport->good() )                          {                              if ( errno != ECONNREFUSED )                              {                                  std::cerr << __FILE__ << ": " << __LINE__                                            << ": Error sending to socket: "                                            << strerror( errno ) << std::endl                                            << "msg = [" << buf << "]\n";                              }                              M_socket.close();                          }                          std::cout << buf << std::endl;                      }                  }                  // read from socket                  if ( FD_ISSET( M_socket.getFD(), &read_fds ) )                  {                      rcss::net::Addr from;                      int len = M_socket.recv( buf, sizeof( buf ) - 1, from );                      if ( len == -1                           && errno != EWOULDBLOCK )                      {                          if ( errno != ECONNREFUSED )                          {                              std::cerr << __FILE__ << ": " << __LINE__                                        << ": Error receiving from socket: "                                        << strerror( errno ) << std::endl;                          }                          M_socket.close();                      }                      else if ( len > 0 )                      {                          M_dest.setPort( from.getPort() );                          M_socket_buf->setEndPoint( M_dest );                          processMsg( buf, len );                      }                  }              }          }      }};namespace {Client * client = static_cast< Client * >( 0 );voidsig_exit_handle( int ){    std::cerr << "\nKilled. Exiting..." << std::endl;    if ( client )    {        delete client;        client =  static_cast< Client * >( 0 );    }    std::exit( EXIT_FAILURE );}}intmain ( int argc, char **argv ){    if ( std::signal( SIGINT, &sig_exit_handle) == SIG_ERR         || std::signal( SIGTERM, &sig_exit_handle ) == SIG_ERR         || std::signal( SIGHUP, &sig_exit_handle ) == SIG_ERR )    {        std::cerr << __FILE__ << ": " << __LINE__                  << ": could not set signal handler: "                  << std::strerror( errno ) << std::endl;        std::exit( EXIT_FAILURE );    }    std::cerr << "Hit Ctrl-C to exit." << std::endl;    std::string server = "localhost";    int port = 6000;    for ( int i = 0; i < argc; ++i )    {        if ( std::strcmp( argv[ i ], "-server" ) == 0 )        {            if ( i + 1 < argc )            {                server = argv[ i + 1 ];                ++i;            }        }        else if ( std::strcmp( argv[ i ], "-port" ) == 0 )        {            if ( i + 1 < argc )            {                port = std::atoi( argv[ i + 1 ] );                ++i;            }        }    }    client = new Client( server, port );    client->run();    return EXIT_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -