Vowpal Wabbit
active_interactor.cc
Go to the documentation of this file.
1 /*
2 Copyright (c) by respective owners including Yahoo!, Microsoft, and
3 individual contributors. All rights reserved. Released under a BSD (revised)
4 license as described in the file LICENSE.
5  */
6 #include <iostream>
7 #include <sstream>
8 #include <stdexcept>
9 #include <string>
10 #include <cstring>
11 #include <cerrno>
12 #include <cstdlib>
13 #ifdef _WIN32
14 #define NOMINMAX
15 #include <WinSock2.h>
16 #else
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <netinet/tcp.h>
22 #include <netdb.h>
23 #endif
24 
25 using std::cerr;
26 using std::endl;
27 
28 int open_socket(const char* host, unsigned short port)
29 {
30  hostent* he;
31  he = gethostbyname(host);
32 
33  if (he == nullptr)
34  {
35  std::stringstream msg;
36  msg << "gethostbyname(" << host << "): " << strerror(errno);
37  cerr << msg.str() << endl;
38  throw std::runtime_error(msg.str().c_str());
39  }
40  int sd = socket(PF_INET, SOCK_STREAM, 0);
41  if (sd == -1)
42  {
43  std::stringstream msg;
44  msg << "socket: " << strerror(errno);
45  cerr << msg.str() << endl;
46  throw std::runtime_error(msg.str().c_str());
47  }
48  sockaddr_in far_end;
49  far_end.sin_family = AF_INET;
50  far_end.sin_port = htons(port);
51  far_end.sin_addr = *(in_addr*)(he->h_addr);
52  memset(&far_end.sin_zero, '\0', 8);
53  if (connect(sd, (sockaddr*)&far_end, sizeof(far_end)) == -1)
54  {
55  std::stringstream msg;
56  msg << "connect(" << host << ':' << port << "): " << strerror(errno);
57  cerr << msg.str() << endl;
58  throw std::runtime_error(msg.str().c_str());
59  }
60  return sd;
61 }
62 
63 int recvall(int s, char* buf, int n)
64 {
65  int total = 0;
66  int ret = recv(s, buf, n, 0);
67  while (ret > 0 && total < n)
68  {
69  total += ret;
70  if (buf[total - 1] == '\n')
71  break;
72  ret = recv(s, buf + total, n, 0);
73  }
74  return total;
75 }
76 
77 int main(int argc, char* argv[])
78 {
79  char buf[256];
80  char *toks, *itok, *ttag;
81  std::string tag;
82  const char* host = "localhost";
83  unsigned short port = ~0;
84  ssize_t pos;
85  int s, ret, queries = 0;
86  std::string line;
87 
88  if (argc > 1)
89  {
90  host = argv[1];
91  }
92  if (argc > 2)
93  {
94  port = atoi(argv[2]);
95  }
96  if (port <= 1024 || port == (unsigned short)(~0u))
97  {
98  port = 26542;
99  }
100 
101  s = open_socket(host, port);
102  size_t id = 0;
103  ret = send(s, &id, sizeof(id), 0);
104  if (ret < 0)
105  {
106  const char* msg = "Could not perform handshake!";
107  cerr << msg << endl;
108  throw std::runtime_error(msg);
109  }
110 
111  while (getline(std::cin, line))
112  {
113  line.append("\n");
114  int len = line.size();
115  const char* cstr = line.c_str();
116  const char* sp = strchr(cstr, ' ');
117  ret = send(s, sp + 1, len - (sp + 1 - cstr), 0);
118  if (ret < 0)
119  {
120  const char* msg = "Could not send unlabeled data!";
121  cerr << msg << endl;
122  throw std::runtime_error(msg);
123  }
124  ret = recvall(s, buf, 256);
125  if (ret < 0)
126  {
127  const char* msg = "Could not receive queries!";
128  cerr << msg << endl;
129  throw std::runtime_error(msg);
130  }
131  buf[ret] = '\0';
132  toks = &buf[0];
133  strsep(&toks, " ");
134  ttag = strsep(&toks, " ");
135  tag = ttag ? std::string(ttag) : std::string("'empty");
136  itok = strsep(&toks, "\n");
137  if (itok == nullptr || itok[0] == '\0')
138  {
139  continue;
140  }
141 
142  queries += 1;
143  std::string imp = std::string(itok) + " " + tag + " |";
144  pos = line.find_first_of('|');
145  line.replace(pos, 1, imp);
146  cstr = line.c_str();
147  len = line.size();
148  ret = send(s, cstr, len, 0);
149  if (ret < 0)
150  {
151  const char* msg = "Could not send labeled data!";
152  cerr << msg << endl;
153  throw std::runtime_error(msg);
154  }
155  ret = recvall(s, buf, 256);
156  if (ret < 0)
157  {
158  const char* msg = "Could not receive predictions!";
159  cerr << msg << endl;
160  throw std::runtime_error(msg);
161  }
162  }
163  close(s);
164  std::cout << "Went through the data by doing " << queries << " queries" << endl;
165  return 0;
166 }
int main(int argc, char *argv[])
int recvall(int s, char *buf, int n)
int open_socket(const char *host, unsigned short port)