diff options
author | Matthias Schiffer <matthias@gamezock.de> | 2008-06-26 00:45:12 +0200 |
---|---|---|
committer | Matthias Schiffer <matthias@gamezock.de> | 2008-06-26 00:45:12 +0200 |
commit | 27fe7a9e94704e7bd5420b0c3b59016943f0a333 (patch) | |
tree | 2565d419ec2c79f8d8b0860a3c11ab5b4824fa21 /src/Net/Listener.cpp | |
parent | 0e38acdaff7ef753f1d4e140eec9dbaec6f7a047 (diff) | |
download | mad-27fe7a9e94704e7bd5420b0c3b59016943f0a333.tar mad-27fe7a9e94704e7bd5420b0c3b59016943f0a333.zip |
Neue Listener-Klasse
Diffstat (limited to 'src/Net/Listener.cpp')
-rw-r--r-- | src/Net/Listener.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp new file mode 100644 index 0000000..b981b20 --- /dev/null +++ b/src/Net/Listener.cpp @@ -0,0 +1,102 @@ +/* + * Listener.cpp + * + * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Listener.h" +#include "ServerConnection.h" +#include <cerrno> +#include <cstring> +#include <fcntl.h> + +#include <iostream> + +namespace Mad { +namespace Net { + +Listener::Listener(const IPAddress &address0) throw(ConnectionException) +: address(address0) { + gnutls_dh_params_init(&dh_params); + gnutls_dh_params_generate2(dh_params, 768); + + sock = socket(PF_INET, SOCK_STREAM, 0); + + if(sock < 0) + throw ConnectionException("socket()", std::strerror(errno)); + + // Set non-blocking flag + int flags = fcntl(sock, F_GETFL, 0); + + if(flags < 0) { + close(sock); + + throw ConnectionException("fcntl()", std::strerror(errno)); + } + + fcntl(sock, F_SETFL, flags | O_NONBLOCK); + + // Set reuse address + flags = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); + + if(bind(sock, address.getSockAddr(), address.getSockAddrLength()) < 0) { + close(sock); + + throw ConnectionException("bind()", std::strerror(errno)); + } + + if(listen(sock, 64) < 0) { + close(sock); + + throw ConnectionException("listen()", std::strerror(errno)); + } +} + +Listener::~Listener() { + shutdown(sock, SHUT_RDWR); + close(sock); + + gnutls_dh_params_deinit(dh_params); +} + +ServerConnection* Listener::getConnection() { + int sd; + struct sockaddr_in sa; + socklen_t addrlen = sizeof(sa); + + while((sd = accept(sock, reinterpret_cast<struct sockaddr*>(&sa), &addrlen)) >= 0) { + connections.push_back(new ServerConnection(sd, IPAddress(sa), dh_params)); + + addrlen = sizeof(sa); + } + + for(std::list<ServerConnection*>::iterator con = connections.begin(); con != connections.end(); con++) { + (*con)->sendReceive(); + + if(!(*con)->isConnecting()) { + ServerConnection *connection = *con; + connections.erase(con); + + return connection; + } + } + + return 0; +} + +} +} |