d9dcb6007f8c6050126b97960c4a755ab8e305c2
1 package be
.nikiroo
.jvcard
.remote
;
3 import java
.io
.BufferedReader
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStreamReader
;
6 import java
.io
.PrintWriter
;
7 import java
.net
.InetAddress
;
8 import java
.net
.Socket
;
9 import java
.util
.Arrays
;
10 import java
.util
.LinkedList
;
11 import java
.util
.List
;
14 * A client or server connection, that will allow you to connect to, send and
15 * receive data to/from a jVCard remote server.
21 public class SimpleSocket
{
23 * The current version of the network protocol.
25 static public final int CURRENT_VERSION
= 1;
28 * The end of block marker.
30 * An end of block marker needs to be on a line on itself to be valid, and
31 * will denote the end of a block of data.
33 static private String EOB
= ".";
36 private PrintWriter out
;
37 private BufferedReader in
;
38 private int version
; // version of the OTHER end, not this one (this one is
39 // CURRENT_VERSION obviously)
41 private String label
; // can be used for debugging
44 * Create a new {@link SimpleSocket} with the given {@link Socket}.
49 public SimpleSocket(Socket s
, String label
) {
55 * Return the label of this {@link SimpleSocket}. This is mainly used for
56 * debugging purposes or user display if any. It is optional.
60 public String
getLabel() {
67 * Open the {@link SimpleSocket} for reading/writing and negotiates the
70 * Note that you <b>MUST</b> call {@link SimpleSocket#close()} when you are
71 * done to release the acquired resources.
74 * TRUE for clients, FALSE for servers (server speaks first)
79 public void open(boolean client
) throws IOException
{
80 out
= new PrintWriter(s
.getOutputStream(), false);
81 in
= new BufferedReader(new InputStreamReader(s
.getInputStream()));
84 version
= new CommandInstance(receiveLine(), -1).getVersion();
85 sendLine(new CommandInstance(Command
.VERSION
, CURRENT_VERSION
)
88 send(new CommandInstance(Command
.VERSION
, CURRENT_VERSION
)
91 send("[Some help info here]");
92 send("you need to reply with your VERSION + end of block");
93 send("please send HELP in a full block or help");
95 version
= new CommandInstance(receiveLine(), -1).getVersion();
100 * Close the connection and release acquired resources.
102 * @return TRUE if everything was closed properly, FALSE if the connection
103 * was broken (in all cases, resources are released)
105 public boolean close() {
106 boolean broken
= false;
110 broken
= out
.checkError();
111 } catch (IOException e
) {
117 } catch (IOException e
) {
122 } catch (IOException ee
) {
135 * Sends lines to the remote server. Do <b>NOT</b> sends the end-of-block
141 * @throws IOException
142 * in case of IO error
144 protected void send(String data
) throws IOException
{
151 if (out
.checkError())
152 throw new IOException();
156 * Sends an end-of-block marker to the remote server.
158 * @throws IOException
159 * in case of IO error
161 public void sendBlock() throws IOException
{
162 sendBlock((List
<String
>) null);
166 * Sends commands to the remote server, then sends an end-of-block marker.
171 * @throws IOException
172 * in case of IO error
174 public void sendLine(String data
) throws IOException
{
175 sendBlock(Arrays
.asList(new String
[] { data
}));
179 * Sends commands to the remote server, then sends an end-of-block marker.
184 * @throws IOException
185 * in case of IO error
187 public void sendBlock(List
<String
> data
) throws IOException
{
189 for (String dataLine
: data
) {
198 * Sends commands to the remote server, then sends an end-of-block marker.
201 * the {@link Command} to send
203 * @throws IOException
204 * in case of IO error
206 public void sendCommand(Command command
) throws IOException
{
207 sendCommand(command
, null);
211 * Sends commands to the remote server, then sends an end-of-block marker.
217 * the parameter for this command if any
219 * @throws IOException
220 * in case of IO error
222 public void sendCommand(Command command
, String param
) throws IOException
{
223 sendLine(new CommandInstance(command
, param
, CURRENT_VERSION
).toString());
227 * Read a line from the remote server.
229 * Do <b>NOT</b> read until the end-of-block marker, and can return said
230 * block without conversion.
232 * @return the read line
234 * @throws IOException
235 * in case of IO error
237 protected String
receive() throws IOException
{
238 String line
= in
.readLine();
243 * Read lines from the remote server until the end-of-block ("\0\n") marker
246 * @return the read lines without the end marker, or NULL if nothing more to
249 * @throws IOException
250 * in case of IO error
252 public List
<String
> receiveBlock() throws IOException
{
253 List
<String
> result
= new LinkedList
<String
>();
255 String line
= receive();
256 for (; line
!= null && !line
.equals(EOB
); line
= receive()) {
267 * Read a line from the remote server then read until the next end-of-block
270 * @return the parsed line, or NULL if nothing more to read
272 * @throws IOException
273 * in case of IO error
275 public String
receiveLine() throws IOException
{
276 List
<String
> lines
= receiveBlock();
278 if (lines
.size() > 0)
285 * Read a line from the remote server and convert it to a
286 * {@link CommandInstance}, then read until the next end-of-block marker.
288 * @return the parsed {@link CommandInstance}
290 * @throws IOException
291 * in case of IO error
293 public CommandInstance
receiveCommand() throws IOException
{
294 String line
= receive();
295 CommandInstance cmd
= new CommandInstance(line
, version
);
301 public String
toString() {
302 String source
= "[not connected]";
303 InetAddress iadr
= s
.getInetAddress();
305 source
= iadr
.getHostName();
307 return getLabel() + " (" + source
+ ")";