3 #include <sys/socket.h>
11 #include "TCPServerSocket.h"
12 #include "PlatformException.h"
13 #include "misc/String.h"
18 TCPServerSocket::TCPServerSocket(int port
) : port(port
) {
19 struct addrinfo hints
, *result
, *rp
;
21 memset(&hints
, 0, sizeof(hints
));
22 hints
.ai_family
= AF_UNSPEC
;
23 hints
.ai_socktype
= SOCK_STREAM
;
24 hints
.ai_flags
= AI_PASSIVE
;
25 hints
.ai_protocol
= 0;
26 hints
.ai_canonname
= NULL
;
30 int ret
= getaddrinfo(NULL
, Misc::String::from
<int>(port
).c_str(), &hints
, &result
);
32 throw PlatformException(Misc::StreamAsString() << "Couldn't resolve hostname: " << gai_strerror(ret
), false);
35 for(rp
= result
; rp
!= NULL
; rp
= rp
->ai_next
) {
36 socket_fd
= socket(rp
->ai_family
, rp
->ai_socktype
, rp
->ai_protocol
);
37 if(socket_fd
== -1) continue;
39 if(bind(socket_fd
, rp
->ai_addr
, rp
->ai_addrlen
) == 0) break;
45 if(rp
== NULL
) throw PlatformException("Couldn't open port for listening: ");
48 if(listen(socket_fd
, 8) == -1) throw PlatformException("Couldn't listen on socket: ");
52 if(setsockopt(socket_fd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(int)) == -1)
53 throw PlatformException("Couldn't set SO_REUSEADDR on socket: ");
56 TCPServerSocket::~TCPServerSocket() {
61 int TCPServerSocket::get_port() const {
62 if(port
!= 0) return port
;
64 /* TODO: find the randomly-allocated port . . . */
68 void TCPServerSocket::accept_connections() {
71 fd_set listen_set
, read_set
;
75 FD_SET(socket_fd
, &listen_set
);
80 read_set
= listen_set
;
82 while(select(socket_fd
+1, &read_set
, NULL
, NULL
, &tv
)) {
83 if(FD_ISSET(socket_fd
, &read_set
)) {
84 s_fd
= accept(socket_fd
, NULL
, 0);
85 socket_list
.push_back(new TCPSocket(s_fd
));
87 read_set
= listen_set
;
91 void TCPServerSocket::remove_invalid_sockets() {
92 socket_list_t::iterator i
= socket_list
.begin();
94 /* NOTE: this is quite inefficient with large amounts of sockets . . . */
95 for(; i
!= socket_list
.end(); i
++) {
96 if(!(*i
)->is_valid()) {
99 i
= socket_list
.begin();
104 void TCPServerSocket::send_data(std::string data
) {
105 socket_list_t::iterator i
= socket_list
.begin();
107 for(; i
!= socket_list
.end(); i
++) {
108 (*i
)->send_data(data
);
112 void TCPServerSocket::send_data(Misc::SmartPointer
<EventQueue
> data
) {
113 while(data
->peek_event()) {
114 std::string data_string
= data
->peek_event()->serialize();
115 std::cout
<< "TCPServerSocket::send_data(): sending \"" << data_string
<< "\"\n";
116 send_data(data_string
);
121 void TCPServerSocket::disconnect_all() {
122 socket_list_t::iterator i
= socket_list
.begin();
123 for(; i
!= socket_list
.end(); i
++) {
124 if((*i
)->is_valid()) (*i
)->disconnect();
128 } // namespace Platform
129 } // namespace Aesalon