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