Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Connection.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000-2003, Jelle Kok, University of Amsterdam
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice, this
00009 list of conditions and the following disclaimer.
00010 
00011 2. Redistributions in binary form must reproduce the above copyright notice,
00012 this list of conditions and the following disclaimer in the documentation
00013 and/or other materials provided with the distribution.
00014 
00015 3. Neither the name of the University of Amsterdam nor the names of its
00016 contributors may be used to endorse or promote products derived from this
00017 software without specific prior written permission.
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00023 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00024 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00025 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00026 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00028 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 */
00030 
00048 #include <errno.h>       // EWOULDBLOCK
00049 #include <string.h>      // strlen
00050 #include <sys/types.h>   // socket
00051 
00052 #ifndef WIN32
00053   #include <unistd.h>      // close
00054   #include <sys/socket.h>  // socket
00055 #endif
00056 
00057 #ifdef Solaris
00058 #include <sys/socket.h>  // AF_INET SOCK_DGRAM
00059 #endif
00060 
00061 #include "Connection.h"
00062 #include "Logger.h"      // LOG
00063 //#include<iostream>
00064 using namespace std;
00065 extern Logger Log; 
00067 /*****************************************************************************/
00068 /********************** CONNECTION *******************************************/
00069 /*****************************************************************************/
00070 
00072 Connection::Connection( )
00073 {
00074   m_iMaxMsgSize = 2048;
00075 }
00076 
00081 Connection::Connection(const char *hostname, int port, int iMaxSize)
00082 {
00083   m_iMaxMsgSize = iMaxSize;
00084   if(  connect( hostname, port ) )
00085     Log.log( 1,"(Connection:connection) Socket connection made with %s:%d",
00086                                                              hostname, port );
00087   else
00088     Log.log( 1,"(Connection:Connection) Could not create connection with %s:%d"
00089                                                           , hostname, port );
00090 }
00091 
00093 Connection::~Connection()
00094 {
00095   disconnect();
00096 }
00097 
00102 bool Connection::connect(const char *host, int port )
00103 {
00104   struct hostent *host_ent;
00105   struct in_addr *addr_ptr;
00106   struct sockaddr_in  cli_addr ;
00107   int    sockfd ;
00108 
00109   m_sock.socketfd = -1 ;
00110 
00111 #ifndef WIN32
00112   if( (host_ent = (struct hostent*)gethostbyname(host)) === NULL)
00113   {
00114     // if not a string, get information from IP adress.
00115   #ifdef Solaris
00116     if( inet_addr(host) == ((in_addr_t)-1) )
00117   #else
00118     if( inet_addr(host) == INADDR_NONE )
00119   #endif
00120     {
00121       cerr << "(Connection::connect) Cannot find host " << host << endl;
00122       return false ;
00123     }
00124   }
00125   else   // get the necessary information from the hostname (string)
00126   {
00127     addr_ptr = (struct in_addr *) *host_ent->h_addr_list;
00128     host = inet_ntoa(*addr_ptr);
00129   }
00130 #else
00131     // winsock initialization
00132   WORD     wVersionRequested;
00133   WSADATA  wsaData;
00134   wVersionRequested = MAKEWORD( 2, 2 );
00135 
00136   if ( WSAStartup( wVersionRequested, &wsaData ) != 0 )
00137       return false;
00138 
00139   if ( LOBYTE( wsaData.wVersion ) != 2 ||
00140        HIBYTE( wsaData.wVersion ) != 2 ) {
00141       WSACleanup();
00142       return false;
00143   }
00144 
00145   if(inet_addr(host) == INADDR_NONE){
00146     if((host_ent = (struct hostent *)gethostbyname(host)) === NULL) {
00147         return false;
00148     } else {
00149         addr_ptr = (struct in_addr *) *host_ent->h_addr_list ;
00150         host = inet_ntoa(*addr_ptr) ;
00151     }
00152   }
00153 #endif
00154   //  Open UDP socket.
00155   if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
00156   {
00157     cerr << "(Connection::connect) Cannot create socket " << host << endl;
00158     return false ;
00159   }
00160 
00161   // insert the information of the client
00162   cli_addr.sin_family      = AF_INET ;
00163   cli_addr.sin_addr.s_addr = htonl(INADDR_ANY) ;
00164   cli_addr.sin_port        = htons(0) ;
00165 
00166   // bind the client to the server socket
00167   if(bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0)
00168   {
00169     cerr << "(Connection::connect) Cannot bind local address " << host << endl;
00170     return false ;
00171   }
00172 
00173   //  Fill in the structure with the address of the server.
00174   m_sock.socketfd = sockfd ;
00175 
00176   m_sock.serv_addr.sin_family       = AF_INET ;
00177   m_sock.serv_addr.sin_addr.s_addr  = inet_addr(host);
00178   m_sock.serv_addr.sin_port         = htons(port) ;
00179 
00180   return true;
00181 }
00182 
00184 void Connection::disconnect( void )
00185 {
00186   if (isConnected() )
00187   {
00188 #ifdef WIN32
00189     closesocket( m_sock.socketfd );
00190 #else
00191     close(m_sock.socketfd) ;
00192 #endif
00193     m_sock.socketfd = -1; // This also 'sets' isConnected() to false
00194   }
00195 }
00196 
00199 bool Connection::isConnected(void) const
00200 {
00201   return(m_sock.socketfd != -1);
00202 }
00203 
00209 int Connection::receiveMessage( char *msg, int maxsize )
00210 {
00211 #ifdef WIN32
00212   int       servlen;
00213 #elif Solaris
00214   int       servlen;
00215 #else
00216   socklen_t servlen ;
00217 #endif
00218   int n;
00219   struct sockaddr_in serv_addr ;
00220 
00221   servlen = sizeof(serv_addr) ;
00222 
00223   // receive message from server
00224   n = recvfrom(m_sock.socketfd, msg, maxsize, 0,
00225                               (struct sockaddr *)&serv_addr, &servlen);
00226 
00227   if(n < 0)                                   // error
00228   {
00229 #ifdef WIN32
00230     if( n == -1 && errno == WSAEWOULDBLOCK)
00231 #else
00232     if( n == -1 && errno == EWOULDBLOCK)
00233 #endif    
00234     {
00235       msg[0] = '\0' ;
00236       return 0 ;
00237     }
00238     else
00239       return -1;
00240   }
00241   else                                       // succesfull, set new server info
00242   {                                          // next message will go to there
00243     m_sock.serv_addr.sin_port = serv_addr.sin_port ;
00244     msg[n] = '\0' ;
00245 
00246     return ( n == 0 ) ? 0 : 1 ;
00247   }
00248 }
00249 
00253 bool Connection::sendMessage( const char *msg )
00254 {
00255   int n;
00256 
00257   n = strlen(msg) + 1 ;
00258   if( sendto(m_sock.socketfd, msg, n, 0,
00259       (struct sockaddr *)&m_sock.serv_addr, sizeof(m_sock.serv_addr)) != n )
00260     return false ;
00261   return true ;
00262 }
00263 
00270 #ifndef WIN32
00271 int Connection::message_loop( FILE *fpin, FILE *fpout )
00272 {
00273   fd_set readfds, readfds_bak;
00274   int in, max_fd, n, ret;
00275   char buf[m_iMaxMsgSize];
00276 
00277   in = fileno( fpin );
00278   FD_ZERO( &readfds );
00279   FD_SET( in, &readfds );
00280   readfds_bak = readfds;
00281   max_fd = ((in > m_sock.socketfd) ? in : m_sock.socketfd) = 1;
00282 
00283   while( 1 )
00284   {
00285     readfds = readfds_bak;
00286     // wait for message from socket or fpin
00287     if(( ret = select( max_fd, &readfds, NULL, NULL, NULL )) < 0 )
00288     {
00289       perror("select");
00290       break;
00291     }
00292     else if( ret != 0 )
00293     {
00294       if( FD_ISSET(in, &readfds))               // file descriptor fpin was set
00295       {
00296         fgets(buf, m_iMaxMsgSize, fpin);        // get the message
00297         if( sendMessage(buf ) == false )        // and send it
00298           break;
00299       }
00300       if( FD_ISSET(m_sock.socketfd, &readfds ) )// file descriptor was set
00301       {
00302         n = receiveMessage(buf, m_iMaxMsgSize); // receive the message
00303         if( n == -1 )
00304           break;
00305         else if( n > 0 )                        // and put it to fpout
00306         {
00307           fputs(buf, fpout);
00308           fputc( '\n', fpout);
00309         }
00310         fflush(stdout);
00311       }
00312     }
00313   }
00314   return 0;
00315 }
00316 #endif
00317 
00318 
00321 void Connection::show( ostream os )
00322 {
00323   if( ! isConnected() )
00324     os << "Not connected" << endl;
00325   else
00326     os << "Connected" << endl;
00327 
00328 }
00329 
00330 /********************** TESTING PURPOSES *************************************/
00331 
00332 /*
00333 int main( void )
00334 {
00335   char strBuf[m_iMaxMsgSize];
00336   Connection c( "localhost", 6000 );
00337   int i;
00338   c.sendMessage( "(init l (version 6.07))" );
00339   while( 1 )
00340   {
00341     i = c.receiveMessage( strBuf, m_iMaxMsgSize );
00342     printf("%d|%s|\n", i, strBuf );
00343   }
00344   return 0;
00345 }
00346 */
00347 
00348 

Generated on Fri Nov 7 11:45:39 2003 for UvA Trilearn 2003 Base Code by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001