MFEM v2.0
isockstream.cpp
Go to the documentation of this file.
00001 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
00002 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
00003 // reserved. See file COPYRIGHT for details.
00004 //
00005 // This file is part of the MFEM library. For more information and source code
00006 // availability see http://mfem.googlecode.com.
00007 //
00008 // MFEM is free software; you can redistribute it and/or modify it under the
00009 // terms of the GNU Lesser General Public License (as published by the Free
00010 // Software Foundation) version 2.1 dated February 1999.
00011 
00012 #include "isockstream.hpp"
00013 #include <iostream>
00014 #include <string.h>
00015 #include <stdlib.h>
00016 #include <errno.h>
00017 #include <netinet/in.h>
00018 #include <netdb.h>
00019 #include <sys/types.h>
00020 #include <sys/socket.h>
00021 #include <unistd.h>
00022 
00023 
00024 isockstream::isockstream(int port)
00025 {
00026    portnum = port;
00027 
00028    if ( (portID = establish()) < 0)
00029       cout << "Server couldn't be established on port "
00030            << portnum << endl;
00031    Buf = NULL;
00032 }
00033 
00034 int isockstream::establish()
00035 {
00036    // char myname[129];
00037    char   myname[] = "localhost";
00038    int    port;
00039    struct sockaddr_in sa;
00040    struct hostent *hp;
00041 
00042    memset(&sa, 0, sizeof(struct sockaddr_in));
00043    // gethostname(myname, 128);
00044    hp= gethostbyname(myname);
00045 
00046    if (hp == NULL)
00047    {
00048       cerr << "isockstream::establish(): gethostbyname() failed!\n"
00049            << "isockstream::establish(): gethostname() returned: '"
00050            << myname << "'" << endl;
00051       error = 1;
00052       return(-1);
00053    }
00054 
00055    sa.sin_family= hp->h_addrtype;
00056    sa.sin_port= htons(portnum);
00057 
00058    if ((port = socket(AF_INET, SOCK_STREAM, 0)) < 0)
00059    {
00060       cerr << "isockstream::establish(): socket() failed!" << endl;
00061       error = 2;
00062       return(-1);
00063    }
00064 
00065    int on=1;
00066    setsockopt(port, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
00067 
00068    if (bind(port,(const sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0)
00069    {
00070       cerr << "isockstream::establish(): bind() failed!" << endl;
00071       close(port);
00072       error = 3;
00073       return(-1);
00074    }
00075 
00076    listen(port, 4);
00077    error = 0;
00078    return(port);
00079 }
00080 
00081 int isockstream::read_data(int s, char *buf, int n){
00082    int bcount;                      // counts bytes read
00083    int br;                          // bytes read this pass
00084 
00085    bcount= 0;
00086    br= 0;
00087    while (bcount < n) {             // loop until full buffer
00088       if ((br= read(s,buf,n-bcount)) > 0) {
00089          bcount += br;                // increment byte counter
00090          buf += br;                   // move buffer ptr for next read
00091       }
00092       else if (br < 0)               // signal an error to the caller
00093       {
00094          error = 4;
00095          return(-1);
00096       }
00097    }
00098    return(bcount);
00099 }
00100 
00101 void isockstream::receive(istringstream **in)
00102 {
00103    int size;
00104    char length[32];
00105 
00106    if ((*in) != NULL)
00107       delete (*in), *in = NULL;
00108 
00109    if (portID == -1)
00110       return;
00111 
00112    if ((socketID = accept(portID, NULL, NULL)) < 0)
00113    {
00114       cout << "Server failed to accept connection." << endl;
00115       error = 5;
00116       return;
00117    }
00118 
00119    if (read(socketID, length, 32) < 0)
00120    {
00121       error = 6;
00122       return;
00123    }
00124    size = atoi(length);
00125 
00126    if (Buf != NULL)
00127       delete [] Buf;
00128    Buf = new char[size+1];
00129    if (size != read_data(socketID, Buf, size))
00130       cout << "Not all the data has been read" << endl;
00131 #ifdef DEBUG
00132    else
00133       cout << "Reading " << size << " bytes is successful" << endl;
00134 #endif
00135    Buf[size] = '\0';
00136 
00137    close(socketID);
00138    (*in) = new istringstream(Buf);
00139 }
00140 
00141 isockstream::~isockstream()
00142 {
00143    if (Buf != NULL)
00144       delete [] Buf;
00145    if (portID != -1)
00146       close(portID);
00147 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines