📄 connection.cpp
字号:
m_SocketFD = new TDataPorter( conn ); if( *strHost && iPort != -1 ) openConnection( strHost, iPort );}/*! This is the destructor of TConnection which closes available connections and frees up all memory used */TConnection::~TConnection(){ closeConnection(); delete m_SocketFD;};/*! This method returns wheather connection is made or not \return bool wheather connection is active */bool TConnection::connected() const{ return m_SocketFD->active();}/*! This method returns connection mode, ie. TCP/UDP \return bool indicating connection mode */ConnectionT TConnection::getConnectionType() const{ return m_SocketFD->getConnectionType();}/*! This method returns local port assigned to connection \return int current local port being used */int TConnection::getLocalPort( ) const{ return m_SelfAddress.sin_port;}/*! This method sets local port to use \param iPort port to use for connections \return bool wheather update was successful */bool TConnection::setLocalPort( int iPort ){ if( connected() ) return false; m_SelfAddress.sin_port = iPort; return true;}/*! This method returns socket descriptor \return socket descriptor */int TConnection::getSocketFD() const{ return m_SocketFD->getSocketFD();}/*! This method makes a network connection to a server listening for connection \param str hostname to connect to \param iPort port to connect on remote machine \return bool wheather connection is made or not */bool TConnection::openConnection( const char *str, int iPort ){ struct hostent *he; if( ( he = gethostbyname( str ) ) == NULL ) { // get the host info herror( "TConnection::gethostbyname" ); return false; } m_SocketFD->reOpen(); m_Remote.sin_family = AF_INET; // host byte order m_Remote.sin_port = htons(iPort); // short, network byte order m_Remote.sin_addr = *((struct in_addr *)he->h_addr); memset( &(m_Remote.sin_zero), '\0', 8 ); // zero the rest of the struct if( getConnectionType() == CONN_TCP && connect( m_SocketFD->getSocketFD(), (struct sockaddr *)&m_Remote, sizeof(struct sockaddr)) == -1 ) { perror("TConnection::openConnection"); return false; } return true;}/*! This method starts listening on port specified for any connection to be made \param iPort port to start listening on \return bool wheather server started listening or not */bool TConnection::startServer( int iPort ){ if( connected() ) return false; m_SocketFD->reOpen(); m_SelfAddress.sin_port = htons( iPort ); // short, network byte order if( bind( m_SocketFD->getSocketFD(), (struct sockaddr *)&m_SelfAddress, sizeof(struct sockaddr) ) == -1 ) { perror("TConnection::bind"); return false; } if( getConnectionType() == CONN_TCP && listen( m_SocketFD->getSocketFD(), MAX_CONN_QUEUE ) == -1 ) { perror("TConnection::listen"); return false; } return true;}/*! This method waits until a connection is made and a client asked for a connection \return bool if listening was successful */bool TConnection::waitForConnection(){ if( getConnectionType() != CONN_TCP ) return false; int new_fd; sockaddr_in their_addr; socklen_t sin_size = sizeof(struct sockaddr_in); if( ( new_fd = accept( m_SocketFD->getSocketFD(), (struct sockaddr *)&their_addr, &sin_size ) ) == -1 ) { perror("TConnection::accept"); return false; } cout << "server: got connection from " << inet_ntoa(their_addr.sin_addr) << endl; if( !fork() ) { // this is the child process m_SocketFD->closeAll(); // child doesn’t need the listener TDataPorter new_socket( CONN_TCP, new_fd ); new_socket.sendMessage( "Hello, world!\n", 14 ); new_socket.closeAll(); exit(0); } close(new_fd); // parent doesn’t need this return true;}/*! This method closes connections on client side, or stops listening with servers \return bool wheather any connection was closed */bool TConnection::closeConnection(){ if(!connected()) return false; m_SocketFD->closeAll(); return true;}/*! This method waits for data to be recieved to the socket \param time_out time in seconds for socket to determine packets are availabe \return bool indicating socket status */bool TConnection::waitForData( int time_out ) const{ fd_set fds; return ( m_SocketFD->waitForData( fds, time_out ) >= 0 );}/*! This method sends a message via a network socket connection made \param strMsg message to send via network connection \return bool wheather message was sent */bool TConnection::sendMessage( const char * strMsg ) const{ return ( sendData( (void*)strMsg, strlen(strMsg) ) );}/*! This method sends a message via a network socket connection made \param data message to send via network connection \param iLength Length of the message \return bool wheather message was sent */bool TConnection::sendData( const void * data, int iLength ) const{ if( !connected() ) return false; if( m_SocketFD->getConnectionType() == CONN_TCP ) return ( m_SocketFD->sendMessage( data, iLength ) > 0 ? true : false ); else return ( m_SocketFD->sendMessageUDP( data, iLength, &m_Remote ) > 0 ? true : false );}/*! This method writes a message to its connected peer \param msg Message to be written for peer \return bool indicating wheather message was written or not */bool TConnection::writeMessage( const char * msg ) const{ return writeMessage( (void*)msg, strlen(msg) );}/*! This method writes a message to its connected peer \param msg Message to be written for peer \param iLength Message length \return bool indicating wheather message was written or not */bool TConnection::writeMessage( const void * msg, int iLength ) const{ return ( m_SocketFD->writeMessage( msg, iLength ) );}/*! This method checks for data to recieve on the connection and returns recieved data \param strMsg place for recieved data to be written on \param iMaxLen maximum length of place to store data on \param time_out maximum t ime to wait for socket to \param close_empty Close the connection if no data recieved \return bool wheather any data was recieved */bool TConnection::recvMessage( char * strMsg, int iMaxLen, int time_out, bool close_empty ){ if( !connected() ) return false; int iBytesRecieved = m_SocketFD->recvMessage( strMsg, iMaxLen - 1, time_out ); if( iBytesRecieved == -1 ) return false; else if( iBytesRecieved == 0 ) { if( close_empty ) { cerr << "Nothing recieved, probably a dead connection, disconnecting" << endl; closeConnection(); } return false; } else return true;}/*! This method reads a message from the connection. When there is no message available, it does not wait for one. \param msg string in which message is stored \param iMaxLength Maximum length of the message \return bool indicating any message were read or not */bool TConnection::readMessage( void * msg, int iMaxLength ) const{ return ( m_SocketFD->readMessage( msg, iMaxLength ) > 0 );}/********************************************************************//******************* Class TRoboCupConnection *********************//********************************************************************//*! TRoboCupConnection constructor to create & initialize connection to simulation server */TRoboCupConnection::TRoboCupConnection( const char * strHost, int iPort ) : TConnection( CONN_TCP, strHost, iPort ){}/*! TRoboCupConnection destructor, only closes connections and frees up memory */TRoboCupConnection::~TRoboCupConnection(){ closeConnection();}/*! This method is the only part needed for sending commands to simulation server, when a connection is ready \param msg message to send to the server \return bool wheather command was sent or not */bool TRoboCupConnection::sendCommand( const char * msg ) const{ if( ! connected() ) return false; // prefix the message with it's payload length unsigned int len = htonl( strlen(msg) ); string prefix( (const char*)&len, sizeof(unsigned int) ); string str = prefix + msg; CommLogger << "Client -> Serever: \"" << str << "\"" << endl; return ( write( getSocketFD(), str.data(), str.size() ) >= 0 );}/*! This method is the only routine needed to get the simulation server messages \param msg place to write message recieved to \param iMaxLen maximum buffer capacity \return bool indicating wheather any message is recieved */bool TRoboCupConnection::getMessage( char * msg, int iMaxLen ) const{ static char buffer[16 * 1024]; unsigned int bytesRead = read( m_SocketFD->getSocketFD(), buffer, sizeof(buffer)); if( bytesRead < sizeof(unsigned int) ) return false; // msg is prefixed with it's total length unsigned int msgLen = ntohl(*(unsigned int*)buffer); if( msgLen > (unsigned)iMaxLen ) return false; // read remaining message segments unsigned int msgRead = bytesRead - sizeof(unsigned int); char *offset = buffer + bytesRead; while( msgRead < msgLen ) { fd_set fds; FD_ZERO( &fds ); FD_SET( m_SocketFD->getSocketFD(), &fds ); if( select(m_SocketFD->getSocketFD() + 1, &fds, 0, 0, 0) > 0 ) { msgRead += read(m_SocketFD->getSocketFD(), offset, sizeof(buffer) - msgRead); offset += msgRead; } } // zero terminate received data (*offset) = 0; strcpy( (char*)msg, string(buffer+sizeof(unsigned int) ).data() ); CommLogger << "Server -> Client: \"" << msg << "\"" << "\n"; return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -