View Javadoc
1   /*
2    * junixsocket
3    *
4    * Copyright 2009-2026 Christian Kohlschütter
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.newsclub.net.unix.demo.server;
19  
20  import java.io.IOException;
21  import java.net.ServerSocket;
22  import java.net.Socket;
23  import java.net.SocketAddress;
24  import java.net.SocketException;
25  import java.util.concurrent.Future;
26  
27  import org.newsclub.net.unix.AFSocketAddress;
28  import org.newsclub.net.unix.AFUNIXSocket;
29  import org.newsclub.net.unix.server.SocketServer;
30  
31  import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
32  
33  /**
34   * An {@link SocketServer} that's just good for demo purposes.
35   *
36   * @author Christian Kohlschütter
37   */
38  @SuppressWarnings("CatchAndPrintStackTrace" /* errorprone */)
39  @SuppressFBWarnings("UNENCRYPTED_SERVER_SOCKET")
40  abstract class DemoServerBase extends SocketServer<SocketAddress, Socket, ServerSocket> {
41    public DemoServerBase(SocketAddress listenAddress) {
42      super(listenAddress);
43    }
44  
45    private static String millisToHumanReadable(int millis, String zeroValue) {
46      if (millis == 0 && zeroValue != null) {
47        return "0 [ms] (" + zeroValue + ")";
48      } else {
49        float secs = millis / 1000f;
50        if ((secs - (int) secs) == 0) {
51          return millis + " [ms] == " + (int) (secs) + "s";
52        } else {
53          return millis + " [ms] == " + secs + "s";
54        }
55      }
56    }
57  
58    @Override
59    protected void onServerStarting() {
60      System.out.println();
61      System.out.println("Creating server: " + getClass().getName());
62      System.out.println("with the following configuration:");
63      System.out.println("- maxConcurrentConnections: " + getMaxConcurrentConnections());
64      System.out.println("- serverTimeout: " + millisToHumanReadable(getServerTimeout(), "none"));
65      System.out.println("- socketTimeout: " + millisToHumanReadable(getSocketTimeout(), "none"));
66      System.out.println("- serverBusyTimeout: " + millisToHumanReadable(getServerBusyTimeout(),
67          "none"));
68    }
69  
70    @Override
71    protected void onServerBound(SocketAddress address) {
72      System.out.println("Created server -- bound to " + address);
73    }
74  
75    @Override
76    protected void onServerBusy(long busySince) {
77      System.out.println("Server is busy");
78    }
79  
80    @Override
81    protected void onServerReady(int activeCount) {
82      System.out.println("Active connections: " + activeCount
83          + "; waiting for the next connection...");
84    }
85  
86    @Override
87    protected void onServerStopped(ServerSocket theServerSocket) {
88      System.out.println("Close server " + theServerSocket);
89    }
90  
91    @Override
92    protected void onSubmitted(Socket socket, Future<?> submit) {
93      System.out.println("Accepted: " + socket);
94    }
95  
96    @Override
97    protected void onBeforeServingSocket(Socket socket) {
98      System.out.println("Serving socket: " + socket);
99      if (socket instanceof AFUNIXSocket) {
100       try {
101         System.out.println("Client's credentials: " + ((AFUNIXSocket) socket).getPeerCredentials());
102       } catch (IOException e) {
103         e.printStackTrace();
104       }
105     }
106   }
107 
108   @Override
109   protected void onServerShuttingDown() {
110     System.out.println("Nothing going on for a long time, I better stop listening");
111   }
112 
113   @Override
114   protected void onSocketExceptionDuringAccept(SocketException e) {
115     e.printStackTrace();
116   }
117 
118   @Override
119   protected void onSocketExceptionAfterAccept(Socket socket, SocketException e) {
120     System.out.println("Closed (not executed): " + socket);
121   }
122 
123   @Override
124   protected void onServingException(Socket socket, Throwable t) {
125     if (socket.isClosed()) {
126       // "Broken pipe", etc.
127       System.out.println("The other end disconnected (" + t.getMessage() + "): " + socket);
128       return;
129     }
130     System.err.println("Exception thrown in " + socket + ", connected: " + socket.isConnected()
131         + ", " + socket.isBound() + "," + socket.isClosed() + "," + socket.isInputShutdown() + ","
132         + socket.isOutputShutdown());
133     t.printStackTrace();
134   }
135 
136   @Override
137   protected void onAfterServingSocket(Socket socket) {
138     System.out.println("Closed: " + socket);
139   }
140 
141   @Override
142   protected void onListenException(Exception e) {
143     e.printStackTrace();
144   }
145 
146   @Override
147   protected ServerSocket newServerSocket() throws IOException {
148     SocketAddress listenAddress = getListenAddress();
149     if (listenAddress instanceof AFSocketAddress) {
150       return ((AFSocketAddress) listenAddress).getAddressFamily().newServerSocket();
151     } else {
152       return new ServerSocket();
153     }
154   }
155 }