server: add a HELLO handshake
[fanfix.git] / src / be / nikiroo / utils / serial / server / ServerString.java
1 package be.nikiroo.utils.serial.server;
2
3 import java.io.IOException;
4 import java.net.Socket;
5 import java.net.UnknownHostException;
6
7 /**
8 * This class implements a simple server that can listen for connections and
9 * send/receive Strings.
10 * <p>
11 * Note: this {@link ServerString} has to be discarded after use (cannot be
12 * started twice).
13 *
14 * @author niki
15 */
16 abstract public class ServerString extends Server {
17 /**
18 * Create a new server that will start listening on the network when
19 * {@link ServerString#start()} is called.
20 *
21 * @param port
22 * the port to listen on, or 0 to assign any unallocated port
23 * found (which can later on be queried via
24 * {@link ServerString#getPort()}
25 * @param key
26 * an optional key to encrypt all the communications (if NULL,
27 * everything will be sent in clear text)
28 *
29 * @throws IOException
30 * in case of I/O error
31 * @throws UnknownHostException
32 * if the IP address of the host could not be determined
33 * @throws IllegalArgumentException
34 * if the port parameter is outside the specified range of valid
35 * port values, which is between 0 and 65535, inclusive
36 */
37 public ServerString(int port, String key) throws IOException {
38 super(port, key);
39 }
40
41 /**
42 * Create a new server that will start listening on the network when
43 * {@link ServerString#start()} is called.
44 *
45 * @param name
46 * the server name (only used for debug info and traces)
47 * @param port
48 * the port to listen on
49 * @param key
50 * an optional key to encrypt all the communications (if NULL,
51 * everything will be sent in clear text)
52 *
53 * @throws IOException
54 * in case of I/O error
55 * @throws UnknownHostException
56 * if the IP address of the host could not be determined
57 * @throws IllegalArgumentException
58 * if the port parameter is outside the specified range of valid
59 * port values, which is between 0 and 65535, inclusive
60 */
61 public ServerString(String name, int port, String key) throws IOException {
62 super(name, port, key);
63 }
64
65 @Override
66 protected ConnectActionServer createConnectActionServer(Socket s) {
67 return new ConnectActionServerString(s, key) {
68 @Override
69 public void action() throws Exception {
70 long id = getNextId();
71 for (String data = rec(); data != null; data = rec()) {
72 String rep = null;
73 try {
74 rep = onRequest(this, data, id);
75 if (isClosing()) {
76 return;
77 }
78 } catch (Exception e) {
79 onError(e);
80 }
81
82 if (rep == null) {
83 rep = "";
84 }
85 send(rep);
86 }
87
88 onRequestDone(id, getBytesReceived(), getBytesSent());
89 }
90
91 @Override
92 protected void onError(Exception e) {
93 ServerString.this.onError(e);
94 }
95 };
96 }
97
98 @Override
99 protected ConnectActionClient getConnectionToMe()
100 throws UnknownHostException, IOException {
101 return new ConnectActionClientString(new Socket((String) null,
102 getPort()), key);
103 }
104
105 /**
106 * This is the method that is called on each client request.
107 * <p>
108 * You are expected to react to it and return an answer (NULL will be
109 * converted to an empty {@link String}).
110 *
111 * @param action
112 * the client action
113 * @param data
114 * the data sent by the client
115 * @param id
116 * an ID to identify this request (will also be re-used for
117 * {@link ServerObject#onRequestDone(long, long, long)}.
118 *
119 * @return the answer to return to the client
120 *
121 * @throws Exception
122 * in case of an exception, the error will only be logged
123 */
124 abstract protected String onRequest(ConnectActionServerString action,
125 String data, long id) throws Exception;
126 }