Began switching the GUI system to use a QSettings object.
[aesalon.git] / src / platform / TCPServerSocket.cpp
blobccaf13d8fe2beaf89f5ec24854e04ca4fa24c7bd
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <arpa/inet.h>
4 #include <cstring>
5 #include <iostream>
6 #include <netdb.h>
7 #include <errno.h>
9 #include "TCPServerSocket.h"
10 #include "PlatformException.h"
11 #include "MemoryEvent.h"
12 #include "misc/String.h"
14 namespace Aesalon {
15 namespace Platform {
17 TCPServerSocket::TCPServerSocket(int port) : port(port) {
18 std::cout << "Constructing TCPServerSocket, port is: " << port << std::endl;
20 struct addrinfo hints, *result, *rp;
22 memset(&hints, 0, sizeof(hints));
23 hints.ai_family = AF_UNSPEC;
24 hints.ai_socktype = SOCK_STREAM;
25 hints.ai_flags = AI_PASSIVE;
26 hints.ai_protocol = 0;
27 hints.ai_canonname = NULL;
28 hints.ai_addr = NULL;
29 hints.ai_next = NULL;
31 int ret = getaddrinfo(NULL, Misc::String::from<int>(port).c_str(), &hints, &result);
32 if(ret != 0) {
33 throw PlatformException(Misc::StreamAsString() << "Couldn't resolve hostname: " << gai_strerror(ret), false);
36 for(rp = result; rp != NULL; rp = rp->ai_next) {
37 socket_fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
38 if(socket_fd == -1) continue;
40 if(bind(socket_fd, rp->ai_addr, rp->ai_addrlen) == 0) break;
42 int e = errno;
43 close(socket_fd);
44 errno = e;
46 if(rp == NULL) throw PlatformException("Couldn't open port for listening: ");
47 freeaddrinfo(result);
49 if(listen(socket_fd, 8) == -1) throw PlatformException("Couldn't listen on socket: ");
52 TCPServerSocket::~TCPServerSocket() {
53 close(socket_fd);
56 int TCPServerSocket::get_port() const {
57 if(port != 0) return port;
59 /* TODO: find the randomly-allocated port . . . */
60 return 0;
63 void TCPServerSocket::accept_connections() {
64 int s_fd;
66 while((s_fd = accept(socket_fd, NULL, 0))) {
67 socket_list.push_back(new TCPSocket(s_fd));
71 void TCPServerSocket::remove_invalid_sockets() {
72 socket_list_t::iterator i = socket_list.begin();
74 /* NOTE: this is quite inefficient with large amounts of sockets . . . */
75 for(; i != socket_list.end(); i ++) {
76 if(!(*i)->is_valid()) {
77 (*i) = 0;
78 socket_list.erase(i);
79 i = socket_list.begin();
84 void TCPServerSocket::send_data(std::string data) {
85 socket_list_t::iterator i = socket_list.begin();
87 for(; i != socket_list.end(); i ++) {
88 (*i)->send_data(data);
92 void TCPServerSocket::send_data(Misc::SmartPointer<EventQueue> data) {
93 while(data->peek_event()) {
94 send_data(data->peek_event().to<MemoryEvent>()->serialize());
95 data->pop_event();
99 } // namespace Platform
100 } // namespace Aesalon