MFEM  v3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
isockstream.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.googlecode.com.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #include "isockstream.hpp"
13 #include <iostream>
14 #include <cstring>
15 #include <cstdlib>
16 #include <errno.h>
17 #ifndef _WIN32
18 #include <netinet/in.h>
19 #include <netdb.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <unistd.h>
23 #else
24 #include <winsock.h>
25 typedef int ssize_t;
26 typedef int socklen_t;
27 #define close closesocket
28 // Link with ws2_32.lib
29 #pragma comment(lib, "ws2_32.lib")
30 #endif
31 
32 using namespace std;
33 
34 namespace mfem
35 {
36 
37 isockstream::isockstream(int port)
38 {
39  portnum = port;
40 
41  if ( (portID = establish()) < 0)
42  cout << "Server couldn't be established on port "
43  << portnum << endl;
44  Buf = NULL;
45 }
46 
47 int isockstream::establish()
48 {
49  // char myname[129];
50  char myname[] = "localhost";
51  int port;
52  struct sockaddr_in sa;
53  struct hostent *hp;
54 
55  memset(&sa, 0, sizeof(struct sockaddr_in));
56  // gethostname(myname, 128);
57  hp= gethostbyname(myname);
58 
59  if (hp == NULL)
60  {
61  cerr << "isockstream::establish(): gethostbyname() failed!\n"
62  << "isockstream::establish(): gethostname() returned: '"
63  << myname << "'" << endl;
64  error = 1;
65  return(-1);
66  }
67 
68  sa.sin_family= hp->h_addrtype;
69  sa.sin_port= htons(portnum);
70 
71  if ((port = socket(AF_INET, SOCK_STREAM, 0)) < 0)
72  {
73  cerr << "isockstream::establish(): socket() failed!" << endl;
74  error = 2;
75  return(-1);
76  }
77 
78  int on=1;
79  setsockopt(port, SOL_SOCKET, SO_REUSEADDR, (char *)(&on), sizeof(on));
80 
81  if (bind(port,(const sockaddr*)&sa,(socklen_t)sizeof(struct sockaddr_in)) < 0)
82  {
83  cerr << "isockstream::establish(): bind() failed!" << endl;
84  close(port);
85  error = 3;
86  return(-1);
87  }
88 
89  listen(port, 4);
90  error = 0;
91  return(port);
92 }
93 
94 int isockstream::read_data(int s, char *buf, int n){
95  int bcount; // counts bytes read
96  int br; // bytes read this pass
97 
98  bcount= 0;
99  br= 0;
100  while (bcount < n) // loop until full buffer
101  {
102  if ((br = recv(s, buf, n - bcount, 0)) > 0)
103  {
104  bcount += br; // increment byte counter
105  buf += br; // move buffer ptr for next read
106  }
107  else if (br < 0) // signal an error to the caller
108  {
109  error = 4;
110  return(-1);
111  }
112  }
113  return(bcount);
114 }
115 
116 void isockstream::receive(std::istringstream **in)
117 {
118  int size;
119  char length[32];
120 
121  if ((*in) != NULL)
122  delete (*in), *in = NULL;
123 
124  if (portID == -1)
125  return;
126 
127  if ((socketID = accept(portID, NULL, NULL)) < 0)
128  {
129  cout << "Server failed to accept connection." << endl;
130  error = 5;
131  return;
132  }
133 
134  if (recv(socketID, length, 32, 0) < 0)
135  {
136  error = 6;
137  return;
138  }
139  size = atoi(length);
140 
141  if (Buf != NULL)
142  delete [] Buf;
143  Buf = new char[size+1];
144  if (size != read_data(socketID, Buf, size))
145  cout << "Not all the data has been read" << endl;
146 #ifdef DEBUG
147  else
148  cout << "Reading " << size << " bytes is successful" << endl;
149 #endif
150  Buf[size] = '\0';
151 
152  close(socketID);
153  (*in) = new istringstream(Buf);
154 }
155 
156 isockstream::~isockstream()
157 {
158  if (Buf != NULL)
159  delete [] Buf;
160  if (portID != -1)
161  close(portID);
162 }
163 
164 }
int socklen_t
Definition: isockstream.cpp:26
int ssize_t
Definition: isockstream.cpp:25