HomeMadeServer.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------
00002 
00003   Program name : Server.cc                                
00004               
00005   Function : An example MRML server
00006 
00007   Creation Date : July 1999           
00008 
00009   Author : Wolfgang Müller
00010 
00011   (some very small parts (< 200 lines)
00012    of this code still stem from 
00013    Jilali Raki's MREP based server)
00014                   
00015   Last modification: August 1999
00016 
00017 
00018   defines: _NON_BLOCKING: if !=0 then the socket will be used as a non-blocking one
00019 
00020   ---------------------------------------------------------------------------*/
00021 
00022 //use stuff by Wolfgang which has not yet been "released" to the group
00023 #define WOLFGANG_DEVELOPER
00024 
00025 // the gift exceptions
00026 #include "libMRML/include/GIFTExceptions.h"
00027 
00028 // c++ standard library stuff
00029 #include <functional>
00030 #include <iostream>
00031 #include <algorithm>
00032 #include <string>
00033 //c standard functions
00034 #include <cstdio>
00035 #include <stdlib.h>
00036 #include <cmath>
00037 
00038 //Sockets
00039 #include <ctime>
00040 #include <unistd.h>
00041 #include <fcntl.h>
00042 #include <sys/time.h>
00043 #include <sys/types.h>
00044 #include <sys/socket.h>
00045 #include <cerrno>
00046 //to be more specific: internet sockets
00047 #include <arpa/inet.h>
00048 #include <netinet/tcp.h>
00049 //will we need the line below?
00050 //#include <linux/socket.h>
00051 
00052 //the expat xml parser by J.Clark
00053 //#include "expat/xmlparse/xmlparse.h"
00054 #include <xmlparse.h>
00055 //a class for using xpat attributes in a nice way
00056 #include "libMRML/include/CAttributeList.h"
00057 
00058 //"classical" gift specific includes
00059 #include "libMRML/include/CRelevanceLevelList.h"
00060 #include "libGIFTAcInvertedFile/include/CDocumentFrequencyList.h"
00061 #include "libGIFTAcInvertedFile/include/CAcInvertedFile.h"
00062 #include "libGIFTQuInvertedFile/include/CQInvertedFile.h"
00063 #include "libMRML/include/TID.h"
00064 #include "libGIFTAcInvertedFile/include/WeightingFunctionsAndNormalizers.h"
00065 #include "libMRML/include/CAccessorElement.h"
00066 #include "libMRML/include/CIDRelevanceLevelPairList.h"
00067 //This is mrml+gift specific
00068 #include "libMRML/include/mrml_const.h" //important constants for parsing
00069 #include "libMRML/include/CAccessorAdminCollection.h"
00070 #include "libMRML/include/CSessionManager.h"
00071 #include "libMRML/include/CAccessor.h" // distance matrix
00072 //for debugging
00073 #define _DEBUG
00074 #define _NON_BLOCKING 0
00075 #include "libMRML/include/CCommunicationHandler.h"
00076 
00077 //the "ID administration subsystem"
00078 TID gID;
00079 
00080 long PORT = 12789; /* port number: this line, for example, is by J. Raki ;-)*/
00081 
00082 
00083 
00084 /***********************************************************************
00085  itoa               
00086                   
00087  Function : Converts integer to String using sprintf
00088                   
00089  Input    : Integer 
00090 
00091  Return   : String 
00092 
00093  ***********************************************************************/
00094 string itoa (int val,int length) {
00095   char *car = new char[length+1];
00096 
00097   for(int i=0;
00098       i<length+1;
00099       i++){
00100     car[i]=0;
00101   };
00102 
00103   
00104   sprintf(car,"%0*2$d",val,length);
00105 
00106   return (string)car; 
00107 }
00108 
00109 string dtoa (double val) {
00110 
00111   char *car = new char[30];
00112 
00113   for(int i=0;
00114       i<30;
00115       i++){
00116     car[i]=0;
00117   };
00118 
00119   
00120   sprintf(car,"%f",val);
00121 
00122   return (string)car; 
00123 
00124 }//..maybe this line is also by J. Raki ;-)
00125 
00126 
00127 
00128 
00129 //waiting that everything has arrived
00130 //
00131 void waitWriteStream(int inWritingSocket){
00132   
00133 
00134   fd_set lStreamsToWaitFor;
00135   FD_ZERO(&lStreamsToWaitFor);
00136   FD_SET(inWritingSocket,&lStreamsToWaitFor);
00137   
00138   timeval lWaitingTime;
00139   lWaitingTime.tv_sec=5;
00140   lWaitingTime.tv_usec=0;
00141 
00142   int lCount=0;
00143   cout << "waiting" << flush;
00144   
00145   while(!select(inWritingSocket+1,
00146     0,
00147     &lStreamsToWaitFor,
00148     0,
00149     &lWaitingTime))lCount++;
00150 
00151   cout << "endwaiting" 
00152        << lCount 
00153        << flush 
00154        << endl;
00155 }
00156 void waitReadStream(int inReadingSocket){
00157   
00158   fd_set lStreamsToWaitFor;
00159   FD_ZERO(&lStreamsToWaitFor);
00160   FD_SET(inReadingSocket,&lStreamsToWaitFor);
00161   
00162   timeval lWaitingTime;
00163   lWaitingTime.tv_sec=5;
00164   lWaitingTime.tv_usec=0;
00165 
00166   //cout << endl << "READwaiting" <<endl<< flush;
00167   
00168   while(!select(inReadingSocket+1,
00169     &lStreamsToWaitFor,
00170     0,
00171     0,
00172     &lWaitingTime));
00173   //cout << "endwaiting" << flush << endl;
00174 }
00175 
00176 void waitExceptionStream(int inExceptioningSocket){
00177   
00178   fd_set lStreamsToWaitFor;
00179   FD_ZERO(&lStreamsToWaitFor);
00180   FD_SET(inExceptioningSocket,&lStreamsToWaitFor);
00181   
00182   timeval lWaitingTime;
00183   lWaitingTime.tv_sec=5;
00184   lWaitingTime.tv_usec=0;
00185 
00186   //cout << endl << "READwaiting" <<endl<< flush;
00187   
00188   while(!select(inExceptioningSocket+1,
00189     &lStreamsToWaitFor,
00190     0,
00191     0,
00192     &lWaitingTime));
00193   cout << "Exc arrived" << flush << endl;
00194 }
00195 
00196 
00197 /***********************************************************************
00198   sendMessage               
00199   
00200   Function : Send a message through the stream s  
00201   
00202   Input    : Socket stream s, number of objects to send
00203 
00204   Return   : 0 if no error else -1
00205   ***********************************************************************/
00206 
00207 #undef _DEBUG
00208 
00209 bool sendMessage(int inSocket,
00210      string inString,
00211      ostream& outLogFile) {
00212 #ifdef _DEBUG
00213   cout << "Message to send: " 
00214        << inString 
00215        << "End of message to send"
00216        << endl 
00217        << flush;
00218 #endif 
00219 
00220   {
00221     string lGIFTHome(".");
00222     
00223     if(getenv("HOME")){
00224       lGIFTHome=string(getenv("HOME"));
00225     }
00226       if(getenv("GIFT_HOME")){
00227   lGIFTHome=string(getenv("GIFT_HOME"));
00228       }
00229   
00230   {
00231     ofstream lOutLastMessageFile(string(lGIFTHome
00232                 +string("/gift-last-out-message.mrml")).c_str());
00233     lOutLastMessageFile << inString
00234     << flush;
00235   }
00236   }
00237 
00238   outLogFile << inString 
00239        << flush;
00240 
00241 
00242   
00243   //i get problems when writing more than 64K to a socket.
00244 #define _SOCKET_WORKAROUND
00245 #ifdef _SOCKET_WORKAROUND
00246   int i=0;
00247   int lWriteSize=0x1000;
00248 
00249   // //this is really embarassing
00250   //sleep(1);
00251   
00252   waitWriteStream(inSocket);
00253   for(;
00254       i<inString.size()/lWriteSize;
00255       i++){
00256     int lOffset=i*lWriteSize;
00257 
00258     int lError=0;
00259     while((lError=write(inSocket,
00260       inString.c_str()+lOffset,
00261       lWriteSize) // The flags are none for the moment.
00262      <=0));
00263     
00264     if(lError>0){
00265       return false;
00266     }
00267 
00268     waitWriteStream(inSocket);
00269   }
00270   if(write(inSocket,
00271      inString.c_str()
00272      +i*lWriteSize,
00273      inString.size()%lWriteSize) // The flags are none for the moment.
00274      <=0 )
00275     return false;
00276 
00277 #else
00278   if(write(inSocket,
00279      inString.c_str(),
00280      inString.size()) // The flags are none for the moment.
00281      <=0 )//this closing bracket has come still untouched from J Raki ;-)
00282     return false;
00283 #endif
00284   
00285 #ifdef _DEBUG
00286   cout << "END:Sending a message... " << endl << flush; 
00287 #endif 
00288 
00289 
00290   waitWriteStream(inSocket);
00291 
00292   cout << "Message successfully sent!"
00293        << endl;
00294 
00295   return true;
00296 }
00297 
00298 /***********************************************************************
00299   ReadMessage               
00300   
00301   Function : read the message coming from the Java Applet using the 
00302   communication protocol  
00303   
00304   Input    : Socket stream s  
00305                 
00306   Return   : 0 if no error else -1
00307   ***********************************************************************/
00308 bool asyncReadChar(int inSocket,char* outChar){
00309   waitReadStream(inSocket);
00310   if(read(inSocket, outChar, 1)>=0)
00311     return true;
00312   else
00313     return false;
00314 }
00315 
00316 
00317 int readMessage(int inSocket,
00318     string& outMessage) { //J. Raki (obsolete)
00319 
00320   cout << "readMessage:" << flush;  
00321 
00322   char lChar[2];
00323   lChar[1]=0;
00324 
00325   while(asyncReadChar(inSocket,lChar)){
00326 #ifdef _DEBUG
00327       cout << ValInt[0] 
00328      << flush;
00329 #endif 
00330       
00331       outMessage += lChar;
00332   }
00333 
00334   return 0;
00335 }
00336 
00337 
00338 #define WITH_GENERATE_DISTANCE_MATRIX
00339 #ifdef WITH_GENERATE_DISTANCE_MATRIX
00340 
00341 void generateDistanceMatrix(const string& inBaseDir,
00342           const string& inOutputName,
00343           const string& inAlgorithm,
00344           const string& inCollection,
00345           int inSkip,
00346           int inTo){
00347 
00348   map<string,int> lURLToPosition;
00349 
00350   string lOutputName=inOutputName
00351     +string(".Algorithm")
00352     +inAlgorithm
00353     +string(".Collection")
00354     +inCollection
00355     +".bin";
00356     
00357 
00358   CSessionManager lSessionManager(inBaseDir+"/gift-sessions.mrml",
00359           inBaseDir+"/gift-config.mrml",
00360           inBaseDir+"/gift-i18n.xml");
00361   
00362   // open a session
00363   string lSessionID(lSessionManager.newSession("DistanceMatrixMaker",""));
00364   // configure the session
00365   CAlgorithm* lConfig(new CAlgorithm("algorithm",
00366              0));
00367   assert(lConfig);
00368   lConfig->addAttribute(mrml_const::algorithm_id,
00369       inAlgorithm);
00370   lConfig->addAttribute(mrml_const::algorithm_type,
00371       inAlgorithm);
00372   lConfig->addAttribute(mrml_const::collection_id,
00373       inCollection);
00374   
00375   lSessionManager.setAlgorithm(lSessionID,
00376              lConfig);
00377 
00378 
00379   fstream lMatrix(lOutputName.c_str(),
00380       fstream::in+fstream::out);
00381 
00382   cout << "----------------------------------------"
00383        << endl
00384        << "I am generating a distance matrix"
00385        << endl
00386        << "Using the algorithm:  " << inAlgorithm
00387        << endl
00388        << "Using the collection: " << inCollection << ","
00389        << endl
00390        << "I am skipping the first " << inSkip << " lines."
00391        << endl
00392        << "I am ending before the  " << inTo << "th  line"
00393        << endl
00394        << "----------------------------------------"
00395        << endl;
00396 
00397   cout << "----------------------------------------"
00398        << endl
00399        << "Getting a list of all IDs in the collection"
00400        << endl
00401        << "SessionID: " << lSessionID
00402        << endl
00403        << "AlgorithmID: " << inAlgorithm
00404        << endl
00405        << "CollectionID: " << inCollection
00406        << endl;
00407 
00408 
00409   /*
00410     Get an accessor. We need this for getting at a list
00411     of all the images. Mabe we do this later using 
00412     a meta data query and coming from the outside.
00413   */
00414 
00415   CAccessorAdminCollection lAccessorAdminCollection(inBaseDir+"/gift-config.mrml");
00416   CAccessorAdmin& lProxy(lAccessorAdminCollection.getProxy(inCollection));
00417   assert(&lProxy);
00418   CAcURL2FTS* lAccessor=(CAcURL2FTS*)lProxy.openAccessor("url2fts");
00419   assert(lAccessor);
00420   list<CAccessorElement> lAccessorElements; 
00421   lAccessor->getAllAccessorElements(lAccessorElements);
00422   
00423   if(lAccessorElements.size()){
00424     
00425     //for guaranteeing a sequence of rising IDs (probably obsolete)
00426     lAccessorElements.sort(CSortByID_CAE());
00427     
00428     int lSize=lAccessorElements.size();
00429     
00430     
00431     
00432     //write the translator if nothing to be skipped
00433     {
00434       ofstream lTranslator(string(lOutputName+".trans").c_str());
00435       int lLine=0;
00436       for(list<CAccessorElement>::const_iterator i=lAccessorElements.begin();
00437     i!=lAccessorElements.end();
00438     i++){
00439   lTranslator << i->getID()
00440         << " "
00441         << lLine
00442         << endl;
00443   lURLToPosition[i->getURL()]=lLine;
00444   lLine++;
00445       }
00446       inTo-=inSkip;
00447     }
00448     
00449     
00450     
00451     
00452     //skip the beginning
00453     {
00454       for(int i=0;
00455     i<inSkip;
00456     i++){
00457   lAccessorElements.pop_front();
00458       }
00459     }
00460     
00461     //skip the beginning also in the matrix
00462     lMatrix.seekp(lSize * inSkip * sizeof(float));
00463     
00464     
00465     int lCount=0;
00466     for(list<CAccessorElement>::const_iterator i=lAccessorElements.begin();
00467   i!=lAccessorElements.end() && lCount<inTo;
00468   i++,lCount++){
00469 
00470       
00471       cout    << "----------------------------------------"
00472         << endl
00473         << "querying for: " 
00474         << i->getID()
00475         << ": "
00476         << i->getURL()
00477         << endl;
00478       
00479       CXMLElement lQuery(mrml_const::query_step,0);
00480       lQuery.addAttribute(mrml_const::algorithm_id,
00481         inAlgorithm);
00482       lQuery.addAttribute(mrml_const::result_size,
00483         long(0x7fffffff));//simply get everything
00484       lQuery.addAttribute(mrml_const::result_cutoff,
00485         0.0);//and do not cut anything off
00486       
00487       CXMLElement* lUserRelevanceList=new CXMLElement(mrml_const::user_relevance_element_list,
00488                   0);
00489       assert(lUserRelevanceList);
00490       
00491       CXMLElement* lUserRelevanceElement=new CXMLElement(mrml_const::user_relevance_element,
00492                0);
00493       lUserRelevanceElement->addAttribute(mrml_const::user_relevance,
00494             1.0);
00495       lUserRelevanceElement->addAttribute(mrml_const::image_location,
00496             i->getURL());
00497 
00498       lQuery.addChild(lUserRelevanceList);
00499       lQuery.addChild(lUserRelevanceElement);
00500       lQuery.moveUp();
00501       lQuery.moveUp();
00502       
00503       string lXML;
00504 
00505       lQuery.toXML(lXML);
00506       
00507       cout << "XML:" 
00508      << lXML
00509      << endl
00510      << "----------------------------------------"
00511      << endl;
00512       
00513       CXMLElement* lResult=lSessionManager
00514   .query(lSessionID,
00515          lQuery);
00516       
00517       {
00518     string lString;
00519     lResult->toXML(lString);
00520     cout << lString 
00521          << endl;
00522       }
00523 
00524       float lOutVector[lSize];
00525       {//fill lOutVecor with zeroes
00526   for(float* p=lOutVector;
00527       p!=lOutVector+lSize;
00528       *(p++)=0){}
00529       }
00530       
00531       float lZero=0.0;
00532       int lLastPosition=0;
00533       
00534       for(CXMLElement::lCChildren::iterator k=lResult->child_list_begin();
00535           k!=lResult->child_list_end();
00536           k++){
00537         for(CXMLElement::lCChildren::iterator j=(*k)->child_list_begin();
00538       j!=(*k)->child_list_end();
00539       j++){
00540       string lURL=(*j)->stringReadAttribute(mrml_const::image_location).second;
00541       double lRelevanceLevel=(*j)->doubleReadAttribute(mrml_const::calculated_similarity).second;
00542       
00543       lOutVector[lURLToPosition[lURL]]=lRelevanceLevel;
00544       
00545       cout << endl << "[" << lURLToPosition[lURL] << "__" << lRelevanceLevel << "]" << flush;
00546         }
00547       }
00548       
00549       lMatrix.write(lOutVector,sizeof(float)*lSize);
00550       lMatrix << flush;
00551       delete lResult;
00552       
00553       cout << endl
00554      << "----------------------------------------"
00555      << "Writing " << sizeof(float)*lSize << " Bytes" << endl
00556 
00557      << "Still to go:" << inTo-lCount-1 << " lines."
00558      << endl
00559      << "----------------------------------------"
00560      << endl;
00561 
00562     }
00563     lMatrix.close();
00564   }else{
00565 
00566   }
00567 }
00568 #endif
00569 
00570 /***********************************************************************
00571   main                
00572   
00573   Function : waits for and accepts a connection from a Java Applet. 
00574   Receives the request from the client and according the 
00575   request, sends the answer to the client.  
00576 
00577   Socket opening code snipped from J.Raki
00578 
00579   ***********************************************************************/         
00580 void main(int argc, char **argv){
00581 
00582   string lConfigurationDirectory(getenv("GIFT_HOME")?getenv("GIFT_HOME"):"");
00583   if(!lConfigurationDirectory.size()){
00584     lConfigurationDirectory=(getenv("HOME")?getenv("HOME"):"");
00585   }
00586 
00587   cout << "GIFT 0.1.3" << endl
00588        << "Usage (server):              gift [<Port> [<Configuration-Directory>]]" << endl
00589        << "making distance matrices:    gift <Port(ignored)> <Configuration-Directory> <Algorithm> <Colection> <from> <to>" << endl
00590        << endl
00591        << endl;
00592 
00593   if(argc>1){
00594     PORT=atoi(argv[1]);
00595   }
00596   if(argc>2){
00597     lConfigurationDirectory=string(argv[2]);
00598   }
00599 
00600   // the communication handler for this application
00601   // class definition is just above in this file
00602   CCommunicationHandler gHandler(lConfigurationDirectory);
00603 
00604 
00605 
00606 
00607 #ifdef WITH_GENERATE_DISTANCE_MATRIX
00608   if(argc==7){
00609     generateDistanceMatrix(lConfigurationDirectory,
00610          string("DistanceMatrix"),
00611          string(argv[3]),
00612          string(argv[4]),
00613          atoi(argv[5]),
00614          atoi(argv[6]));
00615     exit(0);
00616   }
00617 #endif
00618 
00619   cout << "----------------------------------------"
00620        << endl
00621        << "The current configuration directory is: "
00622        << lConfigurationDirectory
00623        << endl;
00624 
00625   cout << "----------------------------------------"
00626        << endl
00627        << "Opening port " << PORT
00628        << endl
00629        << "----------------------------------------"
00630        << endl;
00631 
00632   int lSocketDescriptor;
00633   int lOutSocket;
00634   //a bound socket
00635   //this prototype is copied when accepting
00636   struct sockaddr_in lSocketAddress;
00637   //the copy made of the prototype when accepting
00638   struct sockaddr_in lSocketCopy; 
00639   
00640   lSocketAddress.sin_family = AF_INET ;
00641   /* get the port number */
00642   lSocketAddress.sin_port =  htons(PORT);
00643   lSocketAddress.sin_addr.s_addr = INADDR_ANY ;
00644   
00645   /* create a socket */
00646   if((lSocketDescriptor = socket(PF_INET,
00647          SOCK_STREAM,
00648          IPPROTO_TCP))<0) {
00649     printf("SOCKET error %s\n",strerror(errno)) ;
00650     
00651     exit(1) ;
00652   }
00653 
00654   
00655 
00656   int lOptionOn=1;
00657   if(0 > setsockopt(lSocketDescriptor,
00658         SOL_SOCKET,
00659         SO_REUSEADDR,
00660         (char*)&lOptionOn,
00661         sizeof(lOptionOn))){
00662       cerr << "could not set REUSEADDR: " 
00663      << strerror(errno)
00664      << flush 
00665      << endl;
00666       exit(1);
00667   };  
00668   if(0 > setsockopt(lSocketDescriptor,            /* socket affected */
00669         IPPROTO_TCP,     /* set option at TCP level */
00670         TCP_NODELAY,     /* name of option */
00671         (char *) &lOptionOn,  /* the cast is historical cruft */
00672           
00673         sizeof(lOptionOn))){
00674       cerr << "could not set NODELAY" 
00675      << strerror(errno)
00676      << flush 
00677      << endl;
00678       exit(1);
00679   }
00680 
00681   linger lLinger;
00682   lLinger.l_onoff=1;
00683   lLinger.l_linger=1000;//linger for ten seconds
00684   
00685   /* assigns a name to the socket */
00686   if(bind(lSocketDescriptor,
00687     (struct sockaddr *) &lSocketAddress ,
00688     sizeof(lSocketAddress) ) == -1 ) {
00689     printf("bind error: %s\n",strerror(errno)) ;
00690     exit(1) ;
00691   }
00692   
00693   /*listen to incoming connections */
00694   listen(lSocketDescriptor,
00695    5) ; /* backlog = 5 */
00696   
00697   /* loop to wait for connections */
00698   try{
00699     for(;;){
00700 #ifdef HAVE_LIBSOCKET
00701        int lSocketCopySize = sizeof(lSocketCopy) ;
00702 #else
00703        unsigned int lSocketCopySize = sizeof(lSocketCopy) ;
00704 #endif
00705       /* accept a connection*/
00706       cout << "Waiting for a connection..." << endl << flush;
00707       if(1==_NON_BLOCKING){//setting non-blocking new
00708   long lArgument=0;
00709   long lReturnValue;
00710   lReturnValue=fcntl(lSocketDescriptor,F_GETFL,lArgument);
00711   cout << "before setNonBlocking:" << endl
00712        << "lReturnValue" << lReturnValue
00713        << "lArgument" << lArgument 
00714          << endl;
00715   lReturnValue |= O_NONBLOCK;
00716   fcntl(lSocketDescriptor,F_SETFL,lReturnValue);
00717   lReturnValue=fcntl(lSocketDescriptor,F_GETFL,lArgument);
00718   cout << "after setNonBlocking:" << endl
00719        << "lReturnValue" << lReturnValue
00720        << "lArgument" << lArgument 
00721        << endl;
00722       }
00723       if((lOutSocket=accept(lSocketDescriptor, 
00724           ( struct sockaddr * ) &lSocketCopy, 
00725           &lSocketCopySize)
00726     ) < 0 ) {
00727 
00728   cout << "Error when accepting connection"
00729        << strerror(errno)
00730        << endl;
00731   exit(1) ;
00732       }else{
00733 
00734   if(1==_NON_BLOCKING){//setting non-blocking 
00735     long lArgument=0;
00736     long lReturnValue;
00737     lReturnValue=fcntl(lOutSocket,F_GETFL,lArgument);
00738     cout << "Getting non blocking value for accepted connection:" << endl
00739          << "lReturnValue" << lReturnValue
00740          << "lArgument" << lArgument 
00741          << endl;
00742   }
00743 
00744   gHandler.setSocket(lOutSocket);
00745   cout << "Accepted Connection!" << endl << flush;
00746   if (!gHandler.readAndParse()) {
00747       printf("can't read from socket %s\n",strerror(errno)) ;
00748       //      exit(1) ;
00749   }
00750 
00751   cout << "flushing everything!"
00752        << endl;
00753   fflush(0);
00754 
00755   if(1==_NON_BLOCKING){
00756     cout << "wait for read!"
00757          << endl;
00758     waitReadStream(lOutSocket);
00759   }
00760   cout << "shutting down the socket!"
00761        << endl;
00762   //this is really embarassing
00763   shutdown(lOutSocket,
00764      1);
00765   sleep(1);
00766   close(lOutSocket);
00767       }
00768     }
00769   }
00770   catch(GIFTException& inCaught){
00771     cout << "Caught inServer Main:"
00772    << inCaught
00773    << endl
00774    << flush;
00775   }
00776   catch(...){
00777     cout << "there was an unknown exception" <<endl
00778    << flush;
00779   }
00780   //return 0;
00781 } 
00782 
00783 
00784 
00785 
00786 
00787  
00788 

Generated on Wed Jan 7 00:30:37 2009 for Gift by  doxygen 1.5.6