Multiplexer that allows to read from multiple sockets.
1 // Create a socket to listen to new connections 2 auto listener = new TcpListener(); 3 listener.listen(55001); 4 5 // Create a list to store the future clients 6 TcpSocket[] clients; 7 8 // Create a selector 9 auto selector = new SocketSelector(); 10 11 // Add the listener to the selector 12 selector.add(listener); 13 14 // Endless loop that waits for new connections 15 while (running) 16 { 17 // Make the selector wait for data on any socket 18 if (selector.wait()) 19 { 20 // Test the listener 21 if (selector.isReady(listener)) 22 { 23 // The listener is ready: there is a pending connection 24 auto client = new TcpSocket(); 25 if (listener.accept(client) == Socket.Status.Done) 26 { 27 // Add the new client to the clients list 28 clients~=client; 29 30 // Add the new client to the selector so that we will 31 // be notified when he sends something 32 selector.add(client); 33 } 34 else 35 { 36 // Error, we won't get a new connection 37 } 38 } 39 else 40 { 41 // The listener socket is not ready, test all other sockets (the clients) 42 foreach(client; clients) 43 { 44 if (selector.isReady(client)) 45 { 46 // The client has sent some data, we can receive it 47 auto packet = new Packet(); 48 if (client.receive(packet) == Socket.Status.Done) 49 { 50 ... 51 } 52 } 53 } 54 } 55 } 56 }
$(SOCKET_LINK)
Socket selectors provide a way to wait until some data is available on a set of sockets, instead of just one. This is convenient when you have multiple sockets that may possibly receive data, but you don't know which one will be ready first. In particular, it avoids to use a thread for each socket; with selectors, a single thread can handle all the sockets.
All types of sockets can be used in a selector:
$(PARA A selector doesn't store its own copies of the sockets, it simply keeps a reference to the original sockets that you pass to the "add" function. Therefore, you can't use the selector as a socket container, you must store them outside and make sure that they are alive as long as they are used in the selector (i.e., they cannot be collected by the GC). Using a selector is simple:)