1 package be
.nikiroo
.utils
.serial
;
3 import java
.io
.IOException
;
4 import java
.net
.ServerSocket
;
5 import java
.net
.Socket
;
6 import java
.util
.ArrayList
;
9 import javax
.net
.ssl
.SSLServerSocket
;
10 import javax
.net
.ssl
.SSLServerSocketFactory
;
11 import javax
.net
.ssl
.SSLSocket
;
12 import javax
.net
.ssl
.SSLSocketFactory
;
14 import be
.nikiroo
.utils
.Version
;
16 abstract public class Server
implements Runnable
{
17 static private final String
[] ANON_CIPHERS
= getAnonCiphers();
19 private Version serverVersion
= new Version();
22 private ServerSocket ss
;
23 private boolean started
;
24 private boolean exiting
= false;
26 private Object lock
= new Object();
27 private Object counterLock
= new Object();
29 public Server(Version version
, int port
, boolean ssl
) throws IOException
{
30 this.serverVersion
= version
;
33 this.ss
= createSocketServer(port
, ssl
);
40 new Thread(this).start();
49 // wait = wait before returning (sync VS async) timeout in ms, 0 or -1 for
51 public void stop(final long timeout
, final boolean wait
) {
55 new Thread(new Runnable() {
63 // timeout in ms, 0 or -1 or never
64 private void stop(long timeout
) {
66 if (started
&& !exiting
) {
70 new ConnectActionClient(createSocket(null, port
, ssl
)) {
72 public void action(Version serverVersion
)
78 while (ss
!= null && timeout
> 0 && timeout
> time
) {
82 } catch (Exception e
) {
84 counter
= 0; // will stop the main thread
90 // only return when stopped
91 while (started
|| exiting
) {
94 } catch (InterruptedException e
) {
102 while (started
&& !exiting
) {
104 Socket s
= ss
.accept();
105 new ConnectActionServer(s
) {
106 private Version clientVersion
= new Version();
109 public void action(Version dummy
) throws Exception
{
111 for (Object data
= flush(); true; data
= flush()) {
114 rep
= onRequest(this, clientVersion
, data
);
115 } catch (Exception e
) {
120 } catch (NullPointerException e
) {
121 // Client has no data any more, we quit
126 public void connect() {
135 protected void onClientVersionReceived(Version clientVersion
) {
136 this.clientVersion
= clientVersion
;
141 // Will be covered by @link{Server#stop(long)} for timeouts
142 while (counter
> 0) {
145 } catch (Exception e
) {
152 } catch (Exception e
) {
164 abstract protected Object
onRequest(ConnectActionServer action
,
165 Version clientVersion
, Object data
) throws Exception
;
167 protected void onError(Exception e
) {
169 e
= new Exception("Unknown error");
175 private int count(int change
) {
176 synchronized (counterLock
) {
182 static Socket
createSocket(String host
, int port
, boolean ssl
)
186 s
= SSLSocketFactory
.getDefault().createSocket(host
, port
);
187 ((SSLSocket
) s
).setEnabledCipherSuites(ANON_CIPHERS
);
189 s
= new Socket(host
, port
);
195 static ServerSocket
createSocketServer(int port
, boolean ssl
)
199 ss
= SSLServerSocketFactory
.getDefault().createServerSocket(port
);
200 ((SSLServerSocket
) ss
).setEnabledCipherSuites(ANON_CIPHERS
);
202 ss
= new ServerSocket(port
);
208 private static String
[] getAnonCiphers() {
209 List
<String
> anonCiphers
= new ArrayList
<String
>();
210 for (String cipher
: ((SSLSocketFactory
) SSLSocketFactory
.getDefault())
211 .getSupportedCipherSuites()) {
212 if (cipher
.contains("_anon_")) {
213 anonCiphers
.add(cipher
);
217 return anonCiphers
.toArray(new String
[] {});