MFEM  v3.3
Finite element discretization library
 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.org.
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 {
96  int bcount; // counts bytes read
97  int br; // bytes read this pass
98 
99  bcount= 0;
100  br= 0;
101  while (bcount < n) // loop until full buffer
102  {
103  if ((br = recv(s, buf, n - bcount, 0)) > 0)
104  {
105  bcount += br; // increment byte counter
106  buf += br; // move buffer ptr for next read
107  }
108  else if (br < 0) // signal an error to the caller
109  {
110  error = 4;
111  return (-1);
112  }
113  }
114  return (bcount);
115 }
116 
117 void isockstream::receive(std::istringstream **in)
118 {
119  int size;
120  char length[32];
121 
122  if ((*in) != NULL)
123  {
124  delete (*in), *in = NULL;
125  }
126 
127  if (portID == -1)
128  {
129  return;
130  }
131 
132  if ((socketID = accept(portID, NULL, NULL)) < 0)
133  {
134  cout << "Server failed to accept connection." << endl;
135  error = 5;
136  return;
137  }
138 
139  if (recv(socketID, length, 32, 0) < 0)
140  {
141  error = 6;
142  return;
143  }
144  size = atoi(length);
145 
146  if (Buf != NULL)
147  {
148  delete [] Buf;
149  }
150  Buf = new char[size+1];
151  if (size != read_data(socketID, Buf, size))
152  {
153  cout << "Not all the data has been read" << endl;
154  }
155 #ifdef DEBUG
156  else
157  {
158  cout << "Reading " << size << " bytes is successful" << endl;
159  }
160 #endif
161  Buf[size] = '\0';
162 
163  close(socketID);
164  (*in) = new istringstream(Buf);
165 }
166 
167 isockstream::~isockstream()
168 {
169  if (Buf != NULL)
170  {
171  delete [] Buf;
172  }
173  if (portID != -1)
174  {
175  close(portID);
176  }
177 }
178 
179 }
int socklen_t
Definition: isockstream.cpp:26
int ssize_t
Definition: isockstream.cpp:25