/* D listener written by Christopher E. Miller Modified by Orvid King This code is public domain. You may use it for any purpose. This code has no warranties and is provided 'as-is'. */ import std.algorithm : remove; import std.conv : to; import std.socket : InternetAddress, Socket, SocketException, SocketSet, TcpSocket; import std.stdio : writeln, writefln; void main(string[] args) { ushort port; if (args.length >= 2) port = to!ushort(args[1]); else port = 4444; auto listener = new TcpSocket(); assert(listener.isAlive); listener.blocking = false; listener.bind(new InternetAddress(port)); listener.listen(10); writefln("Listening on port %d.", port); enum MAX_CONNECTIONS = 60; // Room for listener. auto socketSet = new SocketSet(MAX_CONNECTIONS + 1); Socket[] reads; while (true) { socketSet.add(listener); foreach (sock; reads) socketSet.add(sock); Socket.select(socketSet, null, null); for (size_t i = 0; i < reads.length; i++) { if (socketSet.isSet(reads[i])) { char[1024] buf; auto datLength = reads[i].receive(buf[]); if (datLength == Socket.ERROR) writeln("Connection error."); else if (datLength != 0) { writefln("Received %d bytes from %s: \"%s\"", datLength, reads[i].remoteAddress().toString(), buf[0..datLength]); continue; } else { try { // if the connection closed due to an error, remoteAddress() could fail writefln("Connection from %s closed.", reads[i].remoteAddress().toString()); } catch (SocketException) { writeln("Connection closed."); } } // release socket resources now reads[i].close(); reads = reads.remove(i); // i will be incremented by the for, we don't want it to be. i--; writefln("\tTotal connections: %d", reads.length); } } if (socketSet.isSet(listener)) // connection request { Socket sn = null; scope (failure) { writefln("Error accepting"); if (sn) sn.close(); } sn = listener.accept(); assert(sn.isAlive); assert(listener.isAlive); if (reads.length < MAX_CONNECTIONS) { writefln("Connection from %s established.", sn.remoteAddress().toString()); reads ~= sn; writefln("\tTotal connections: %d", reads.length); } else { writefln("Rejected connection from %s; too many connections.", sn.remoteAddress().toString()); sn.close(); assert(!sn.isAlive); assert(listener.isAlive); } } socketSet.reset(); } }