MPQC  3.0.0-alpha
socket.hpp
1 #ifndef MPQC_ARRAY_SOCKET_HPP
2 #define MPQC_ARRAY_SOCKET_HPP
3 
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <netinet/in.h>
7 #include <arpa/inet.h>
8 #include <unistd.h>
9 #include <netdb.h>
10 #include <limits.h>
11 #include <ifaddrs.h>
12 
13 namespace mpqc {
14 namespace detail {
15 
16  struct ArraySocket {
17 
18  typedef sockaddr Address;
19 
20  static void assert_(bool cond, const std::string &msg) {
21  if (!cond) {
22  perror(msg.c_str());
23  throw std::runtime_error(msg + " failed");
24  }
25  }
26 
27  ArraySocket() {
28  this->fd_ = -1;
29  }
30 
31  void start() {
32 
33  // sockaddr addr;
34  // {
35  // struct ifaddrs *ifs;
36  // if (getifaddrs(&ifs) == -1) {
37  // perror("getifaddrs");
38  // exit(EXIT_FAILURE);
39  // }
40  // /* Walk through linked list, maintaining head pointer so we
41  // can free list later */
42  // for (auto ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) {
43  // if (ifa->ifa_addr == NULL) continue;
44  // if (ifa->ifa_addr->sa_family == AF_INET) {
45  // struct sockaddr_in *sin = (struct sockaddr_in*)ifa->ifa_addr;
46  // printf("Interface %s, addr=%s\n",
47  // ifa->ifa_name, inet_ntoa(sin->sin_addr));
48  // }
49  // }
50  // freeifaddrs(ifs);
51  // }
52 
53  struct in_addr in;
54  {
55  int err;
56  char hostname[512];
57  struct hostent *h;
58  assert_(::gethostname(hostname, sizeof(hostname)) > -1, "gethostname");
59  assert_((h = ::gethostbyname(hostname)), "gethostbyname");
60  if (h->h_addrtype == AF_INET) {
61  in = *(in_addr*)h->h_addr;
62  // //err = inet_pton(AF_INET, h->h_addr, &in);
63  // // if (err <= 0) perror("inet_pton");
64  // printf("using address %s(%i)\n", inet_ntoa(in), in.s_addr);
65  }
66  }
67 
68  struct sockaddr_in sin;
69  sin.sin_family = AF_INET;
70  sin.sin_port = 0;
71  sin.sin_addr.s_addr = in.s_addr;
72  memset(sin.sin_zero, '\0', sizeof(sin.sin_zero));
73 
74  int sock;
75  assert_((sock = ::socket(PF_INET, SOCK_STREAM, 0)) > -1, "socket");
76  assert_(::bind(sock, (struct sockaddr*)&sin, sizeof(sin)) > -1, "bind");
77  assert_(::listen(sock, 10) > -1, "listen");
78 
79  this->fd_ = sock;
80 
81  {
82  Address addr = this->address();
83  printf("ArrayServer running on %s:%i\n",
84  inet_ntoa(((sockaddr_in*)&addr)->sin_addr),
85  ((sockaddr_in*)&addr)->sin_port);
86  }
87 
88  }
89 
90  Address address() const {
91  struct sockaddr addr;
92  socklen_t len = sizeof(addr);
93  assert_(getsockname(this->fd_, &addr, &len) > -1, "getsockname");
94  return addr;
95  }
96 
97  template<typename T>
98  void wait(T *data) const {
99  struct sockaddr_storage addr;
100  socklen_t addrlen = sizeof(addr);
101  int fd, bytes;
102  assert_((fd = ::accept(this->fd_, (sockaddr*)&addr, &addrlen)) > -1,
103  "accept");
104  assert_((bytes = ::recv(fd, data, sizeof(T), 0)) > -1, "recv");
105  assert_(::close(fd) > -1, "close");
106  if (bytes != sizeof(T)) {
107  throw std::runtime_error("wrong number of bytes received");
108  }
109  }
110 
111  template<typename T>
112  static void send(const T *data, struct sockaddr addr) {
113  int fd;
114  assert_((fd = ::socket(AF_INET, SOCK_STREAM, 0)) > -1, "socket");
115  assert_(::connect(fd, &addr, sizeof(addr)) > -1, "connect");
116  assert_(::send(fd, data, sizeof(T), 0) > -1, "send");
117  assert_(::close(fd) > -1, "close");
118  }
119 
120  private:
121  int fd_;
122 
123  };
124 
125 } // namespace detail
126 } // namespace mpqc
127 
128 #endif // MPQC_ARRAY_SOCKET_HPP
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37
sc::in
bool in(const OrbitalSpace &s1, const OrbitalSpace &s2)
in(s1,s2) returns true if s1 is in s2
mpqc::detail::ArraySocket
Definition: socket.hpp:16

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.