summaryrefslogtreecommitdiffstats
path: root/src/Net/Listener.cpp
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2008-06-29 20:46:02 +0200
committerMatthias Schiffer <matthias@gamezock.de>2008-06-29 20:46:02 +0200
commit7be6ee9c1cd2c2c5172ad4a094b67c25d6c5b72c (patch)
tree1400e3029fedc413f58b8c3f3e01cfe47abf0383 /src/Net/Listener.cpp
parentee5c5c9f65556b542ab81942e5a024ba84173762 (diff)
downloadmad-7be6ee9c1cd2c2c5172ad4a094b67c25d6c5b72c.tar
mad-7be6ee9c1cd2c2c5172ad4a094b67c25d6c5b72c.zip
Linger-Option der Sockets ausschalten
Diffstat (limited to 'src/Net/Listener.cpp')
-rw-r--r--src/Net/Listener.cpp62
1 files changed, 31 insertions, 31 deletions
diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp
index 981b3c7..3b2e3d6 100644
--- a/src/Net/Listener.cpp
+++ b/src/Net/Listener.cpp
@@ -32,36 +32,36 @@ 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));
-
+
+ // Don't linger
+ struct linger linger = {1, 0};
+ setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
+
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));
}
}
@@ -71,66 +71,66 @@ Listener::~Listener() {
(*con)->disconnect();
delete *con;
}
-
+
shutdown(sock, SHUT_RDWR);
close(sock);
-
+
gnutls_dh_params_deinit(dh_params);
}
std::vector<struct pollfd> Listener::getPollfds() const {
std::vector<struct pollfd> pollfds;
-
+
struct pollfd fd = {sock, POLLIN, 0};
pollfds.push_back(fd);
-
+
for(std::list<ServerConnection*>::const_iterator con = connections.begin(); con != connections.end(); ++con)
pollfds.push_back((*con)->getPollfd());
-
+
return pollfds;
}
ServerConnection* Listener::getConnection(const std::map<int,const short*> &pollfdMap) {
// TODO: Logging
-
+
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) {
std::map<int,const short*>::const_iterator events = pollfdMap.find((*con)->getSocket());
-
+
if(events != pollfdMap.end())
(*con)->sendReceive(*events->second);
else
(*con)->sendReceive();
}
-
+
for(std::list<ServerConnection*>::iterator con = connections.begin(); con != connections.end();) {
if(!(*con)->isConnected()) {
delete *con;
connections.erase(con++); // Erase unincremented iterator
-
+
continue;
}
-
+
if(!(*con)->isConnecting()) {
ServerConnection *connection = *con;
connections.erase(con);
-
+
return connection;
}
-
+
++con;
}
-
+
return 0;
}