Began removal of platform/. The Monitor:: namespace is completely converted.
[aesalon.git] / src / monitor / TCPSocket.cpp
blob87b14f6d02f37116bfb7919b288c68cb19b19824
1 #include <iostream>
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <arpa/inet.h>
5 #include <netdb.h>
6 #include <cstring>
7 #include <errno.h>
9 #include "TCPSocket.h"
10 #include "misc/StreamAsString.h"
11 #include "misc/String.h"
12 #include "misc/Exception.h"
14 namespace Aesalon {
15 namespace Monitor {
17 TCPSocket::TCPSocket(std::string host, int port) {
18 struct addrinfo hints, *result;
20 memset(&hints, 0, sizeof(hints));
21 hints.ai_family = AF_UNSPEC;
22 hints.ai_socktype = SOCK_STREAM;
23 hints.ai_flags = hints.ai_protocol = 0;
24 int ret = getaddrinfo(host.c_str(), Misc::String::from<int>(port).c_str(), &hints, &result);
25 if(ret != 0) {
26 throw Misc::Exception(Misc::StreamAsString() << "Couldn't resolve hostname: " << gai_strerror(ret));
29 if(result->ai_next != NULL) {
30 std::cout << "Warning: Hostname \"" << host << "\" resolves to multiple IPs. Using the first." << std::endl;
34 socket_fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
35 if(socket_fd == -1) throw Misc::Exception(Misc::StreamAsString() << "Couldn't create socket: " << strerror(errno));
37 if(connect(socket_fd, result->ai_addr, result->ai_addrlen) == -1) {
38 close(socket_fd);
39 throw Misc::Exception(Misc::StreamAsString() << "Couldn't connect to host: " << strerror(errno));
42 /* Socket is now connected. */
43 valid = true;
45 TCPSocket::~TCPSocket() {
46 if(socket_fd) close(socket_fd);
49 void TCPSocket::send_data(std::string data) {
50 int sent = write(socket_fd, data.c_str(), data.length()+1);
51 if(sent == -1) valid = false;
54 std::string TCPSocket::get_data() {
55 if(!is_valid()) return "";
56 uint16_t size;
57 read(socket_fd, &size, 2);
58 size = ntohs(size);
60 std::string data;
62 while(size) {
63 char c;
64 int ret = read(socket_fd, &c, 1);
65 if(ret == -1) {
66 if(errno == EAGAIN) continue;
67 else {
68 valid = false;
69 break;
72 data += c;
73 size --;
76 return data;
79 void TCPSocket::disconnect() {
80 if(socket_fd) {
81 close(socket_fd);
82 socket_fd = 0;
86 } // namespace Monitor
87 } // namespace Aesalon