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

Connection.C

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000,2001, 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 */
00043 #include <errno.h>       // EWOULDBLOCK
00044 #include <unistd.h>      // close
00045 #include <string.h>      // strlen
00046 #include <sys/types.h>   // socket
00047 #include <sys/socket.h>  // socket
00048 
00049 #ifdef Solaris
00050 #include <sys/socket.h>  // AF_INET SOCK_DGRAM
00051 #endif
00052 
00053 #include "Connection.h"
00054 #include "Logger.h"      // LOG
00055 
00056 extern Logger Log; 
00058 /******************************************************************************/
00059 /********************** CONNECTION ********************************************/
00060 /******************************************************************************/
00061 
00063 Connection::Connection( )
00064 {
00065   m_iMaxMsgSize = 2048;
00066 }
00067 
00072 Connection::Connection(const char *hostname, int port, int iMaxSize)
00073 {
00074   m_iMaxMsgSize = iMaxSize;
00075   if(  connect( hostname, port ) )
00076     Log.log( 1, "(Connection:connection) Socket connection made with %s:%d",
00077                                                              hostname, port );
00078   else
00079     Log.log( 1, "(Connection:Connection) Could not create connection with %s:%d"
00080                                                           , hostname, port );
00081 }
00082 
00084 Connection::~Connection()
00085 {
00086   disconnect();
00087 }
00088 
00093 bool Connection::connect(const char *host, int port )
00094 {
00095   struct hostent *host_ent;
00096   struct in_addr *addr_ptr;
00097   struct sockaddr_in  cli_addr ;
00098   int    sockfd ;
00099 
00100   m_sock.socketfd = -1 ;
00101 
00102   if( (host_ent = (struct hostent*)gethostbyname(host)) === NULL)
00103   {
00104     // if not a string, get information from IP adress.
00105 #ifdef Solaris
00106     if( inet_addr(host) == ((in_addr_t)-1) )
00107 #else
00108     if( inet_addr(host) == INADDR_NONE )
00109 #endif
00110     {
00111       cerr << "(Connection::connect) Cannot find host " << host << endl;
00112       return false ;
00113     }
00114   }
00115   else   // get the necessary information from the hostname (string)
00116   {
00117     addr_ptr = (struct in_addr *) *host_ent->h_addr_list;
00118     host = inet_ntoa(*addr_ptr);
00119   }
00120 
00121   //  Open UDP socket.
00122   if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
00123   {
00124     cerr << "(Connection::connect) Cannot create socket " << host << endl;
00125     return false ;
00126   }
00127 
00128   // insert the information of the client
00129   cli_addr.sin_family      = AF_INET ;
00130   cli_addr.sin_addr.s_addr = htonl(INADDR_ANY) ;
00131   cli_addr.sin_port        = htons(0) ;
00132 
00133   // bind the client to the server socket
00134   if(bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0)
00135   {
00136     cerr << "(Connection::connect) Cannot bind local address " << host << endl;
00137     return false ;
00138   }
00139 
00140   //  Fill in the structure with the address of the server.
00141   m_sock.socketfd = sockfd ;
00142 
00143   m_sock.serv_addr.sin_family       = AF_INET ;
00144   m_sock.serv_addr.sin_addr.s_addr  = inet_addr(host);
00145   m_sock.serv_addr.sin_port         = htons(port) ;
00146 
00147   return true;
00148 }
00149 
00151 void Connection::disconnect( void )
00152 {
00153   if (isConnected() )
00154   {
00155     close(m_sock.socketfd) ;
00156     m_sock.socketfd = -1; // This also 'sets' isConnected() to false
00157   }
00158 }
00159 
00162 bool Connection::isConnected(void) const
00163 {
00164   return(m_sock.socketfd != -1);
00165 }
00166 
00172 int Connection::receiveMessage( char *msg, int maxsize )
00173 {
00174 #ifdef Solaris
00175   int       servlen;
00176 #else
00177   socklen_t servlen ;
00178 #endif
00179   int n;
00180   struct sockaddr_in serv_addr ;
00181 
00182   servlen = sizeof(serv_addr) ;
00183 
00184   // receive message from server
00185   n = recvfrom(m_sock.socketfd, msg, maxsize, 0,
00186                               (struct sockaddr *)&serv_addr, &servlen);
00187 
00188   if(n < 0)                                   // error
00189   {
00190     if( n == -1 && errno == EWOULDBLOCK)
00191     {
00192       msg[0] = '\0' ;
00193       return 0 ;
00194     }
00195     else
00196       return -1;
00197   }
00198   else                                       // succesfull, set new server info
00199   {                                          // next message will go to there
00200     m_sock.serv_addr.sin_port = serv_addr.sin_port ;
00201     msg[n] = '\0' ;
00202 
00203     return ( n == 0 ) ? 0 : 1 ;
00204   }
00205 }
00206 
00210 bool Connection::sendMessage( const char *msg )
00211 {
00212   int n;
00213 
00214   n = strlen(msg) ;
00215   if( sendto(m_sock.socketfd, msg, n, 0,
00216       (struct sockaddr *)&m_sock.serv_addr, sizeof(m_sock.serv_addr)) != n )
00217     return false ;
00218   return true ;
00219 }
00220 
00227 int Connection::message_loop( FILE *fpin, FILE *fpout )
00228 {
00229   fd_set readfds, readfds_bak;
00230   int in, max_fd, n, ret;
00231   char buf[m_iMaxMsgSize];
00232 
00233   in = fileno( fpin );
00234   FD_ZERO( &readfds );
00235   FD_SET( in, &readfds );
00236   readfds_bak = readfds;
00237   max_fd = ((in > m_sock.socketfd) ? in : m_sock.socketfd) = 1;
00238 
00239   while( 1 )
00240   {
00241     readfds = readfds_bak;
00242     // wait for message from socket or fpin
00243     if(( ret = select( max_fd, &readfds, NULL, NULL, NULL )) < 0 )
00244     {
00245       perror("select");
00246       break;
00247     }
00248     else if( ret != 0 )
00249     {
00250       if( FD_ISSET(in, &readfds))              // file descriptor fpin was set
00251       {
00252         fgets(buf, m_iMaxMsgSize, fpin);             // get the message
00253         if( sendMessage(buf ) == false )       // and send it
00254           break;
00255       }
00256       if( FD_ISSET(m_sock.socketfd, &readfds ) ) // file descriptor socket was set
00257       {
00258         n = receiveMessage(buf, m_iMaxMsgSize);      // receive the message
00259         if( n == -1 )
00260           break;
00261         else if( n > 0 )                       // and put it to fpout
00262         {
00263           fputs(buf, fpout);
00264           fputc( '\n', fpout);
00265         }
00266         fflush(stdout);
00267       }
00268     }
00269   }
00270   return 0;
00271 }
00272 
00273 
00276 void Connection::show( ostream os )
00277 {
00278   if( ! isConnected() )
00279     os << "Not connected" << endl;
00280   else
00281     os << "Connected" << endl;
00282 
00283 }
00284 
00285 /********************** TESTING PURPOSES **************************************/
00286 
00287 /*
00288 int main( void )
00289 {
00290   char strBuf[m_iMaxMsgSize];
00291   Connection c( "localhost", 6000 );
00292   int i;
00293   c.sendMessage( "(init l (version 6.07))" );
00294   while( 1 )
00295   {
00296     i = c.receiveMessage( strBuf, m_iMaxMsgSize );
00297     printf("%d|%s|\n", i, strBuf );
00298   }
00299   return 0;
00300 }
00301 */
00302 
00303 

Generated on Thu Mar 7 00:37:42 2002 for UvA Trilearn 2001 by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001