MFEM v2.0
|
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 }