Adding a (potential) initialization for Alarm; Modifying IoTSocket to allocate a...
[iot2.git] / iotjava / iotrmi / Java / IoTSocket.java
1 package iotrmi.Java;
2
3 // Java libraries
4 import java.io.*;
5 import java.net.*;
6 import java.awt.*;
7 import java.util.*;
8 import java.nio.ByteBuffer;
9
10
11 /** Class IoTSocket is the basic class for IoT RMI
12  *  socket communication. This class will be extended
13  *  by both IoTSocketServer and IoTSocketClient
14  *  <p>
15  *  Adapted from Java/C++ socket implementation
16  *  by Keith Vertanen
17  *  @see        <a href="https://www.keithv.com/software/socket/</a>
18  *
19  * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
20  * @version     1.0
21  * @since       2016-08-17
22  */
23 public abstract class IoTSocket {
24
25         /**
26          * Class Properties
27          */
28         protected byte data[];
29         protected int port;
30         protected Socket sock;
31         protected BufferedInputStream input;
32         protected BufferedOutputStream output;
33
34         /**
35          * Class Constant
36          */
37         protected static int BUFFSIZE = 128000; // how many bytes our incoming buffer can hold (original)
38         //protected static int BUFFSIZE = 8388608;      // 8388608 = 2^23 bytes of memory (8MB) - this is required by our IHome speaker driver
39         protected static int MSG_LEN_SIZE = 4;  // send length in the size of integer (4 bytes)
40
41         /**
42          * Default constructor
43          */
44         protected IoTSocket(int _port) throws IOException
45         {
46                 port = _port;
47                 data = new byte[BUFFSIZE];
48         }
49
50
51         /**
52          * sendBytes() sends an array of bytes
53          */
54         public synchronized void sendBytes(byte vals[]) throws IOException
55         {
56                 int len = vals.length;
57                 // Write the length first - convert to array of 4 bytes
58                 ByteBuffer bb = ByteBuffer.allocate(MSG_LEN_SIZE);
59                 bb.putInt(len);
60                 output.write(bb.array(), 0, MSG_LEN_SIZE);
61                 output.flush();
62                 // Write the byte array
63                 output.write(vals, 0, len);
64                 output.flush();
65                 receiveAck();
66                 sendAck();
67         }
68
69
70         /**
71          * receiveBytes() receives an array of bytes
72          */
73         public synchronized byte[] receiveBytes(byte val[]) throws IOException
74         {
75                 int i;
76                 int totalbytes = 0;
77                 int numbytes;
78
79                 // Wait until input is available
80                 while(input.available() == 0);
81                 // Read the maxlen first - read 4 bytes here
82                 byte[] lenBytes = new byte[MSG_LEN_SIZE];
83                 input.read(lenBytes, 0, MSG_LEN_SIZE);
84                 int maxlen = ByteBuffer.wrap(lenBytes).getInt();
85                 // Receive until maxlen
86                 if (maxlen>BUFFSIZE) {
87                         System.out.println("IoTSocketClient/Server: Sending more bytes then will fit in buffer! Number of bytes: " + maxlen);
88                         // Allocate a bigger array when needed
89                         int newLen = 2;
90                         while (newLen < maxlen) // Shift until we get a new buffer size that's bigger than maxLen (basically power of 2)
91                                 newLen = newLen << 1;
92                         System.out.println("IoTSocketClient/Server: Allocating a bigger buffer now with size: " + newLen);
93                         data = new byte[newLen];
94                 }
95                 val = new byte[maxlen];
96                 while (totalbytes < maxlen)
97                 {
98                         numbytes = input.read(data);
99                         // copy the bytes into the result buffer
100                         for (i=totalbytes; i<totalbytes+numbytes; i++)
101                                 val[i] = data[i-totalbytes];
102                         totalbytes += numbytes;
103                 }
104                 // we now send an acknowledgement to the server to let them
105                 // know we've got it
106                 sendAck();
107                 receiveAck();
108
109                 return val;
110         }
111
112
113         /**
114          * Close socket connection
115          */
116         public synchronized void close() throws IOException
117         {
118                 sock.close();
119         }
120
121
122         /**
123          * Send ACK
124          */
125         public synchronized void sendAck() throws IOException
126         {
127                 int ack;
128                 ack = 0;
129                 output.write(ack);
130                 output.flush();
131         }
132
133
134         /**
135          * Receive ACK
136          */
137         public synchronized void receiveAck() throws IOException
138         {
139                 int ack;
140                 ack = (int) input.read();
141         }
142 }