8 import java.nio.ByteBuffer;
10 import java.util.concurrent.Semaphore;
13 /** Class IoTSocket is the basic class for IoT RMI
14 * socket communication. This class will be extended
15 * by both IoTSocketServer and IoTSocketClient
17 * Adapted from Java/C++ socket implementation
19 * @see <a href="https://www.keithv.com/software/socket/</a>
21 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
25 public abstract class IoTSocket {
30 protected byte data[];
31 protected int localPort;
33 protected Socket sock;
34 protected BufferedInputStream input;
35 protected BufferedOutputStream output;
37 //protected static Semaphore sendRecvMutex = new Semaphore(1);
42 protected static int BUFFSIZE = 128000; // how many bytes our incoming buffer can hold (original)
43 //protected static int BUFFSIZE = 8388608; // 8388608 = 2^23 bytes of memory (8MB) - this is required by our IHome speaker driver
44 protected static int MSG_LEN_SIZE = 4; // send length in the size of integer (4 bytes)
49 protected IoTSocket(int _port) throws IOException
53 data = new byte[BUFFSIZE];
57 protected IoTSocket(int _localPort, int _port) throws IOException
59 localPort = _localPort;
61 data = new byte[BUFFSIZE];
66 * sendBytes() sends an array of bytes
68 public synchronized void sendBytes(byte vals[]) throws IOException
70 int len = vals.length;
71 // Write the length first - convert to array of 4 bytes
72 ByteBuffer bb = ByteBuffer.allocate(MSG_LEN_SIZE);
74 output.write(bb.array(), 0, MSG_LEN_SIZE);
75 //System.out.println("Sender about to send: " + Arrays.toString(bb.array()));
77 // Write the byte array
78 output.write(vals, 0, len);
79 //System.out.println("Sender sending: " + len);
81 //System.out.println("Sender about to receive ACK!");
83 //System.out.println("Sender about to send ACK!\n\n");
89 * receiveBytes() receives an array of bytes
91 public synchronized byte[] receiveBytes(byte val[]) throws IOException
97 // Wait until input is available
98 if (input.available() == 0) {
102 //System.out.println("Receiver about to receive: " + input.available());
103 // Read the maxlen first - read 4 bytes here
104 byte[] lenBytes = new byte[MSG_LEN_SIZE];
105 input.read(lenBytes, 0, MSG_LEN_SIZE);
106 //System.out.println("Receiver lenBytes: " + Arrays.toString(lenBytes));
107 int maxlen = ByteBuffer.wrap(lenBytes).getInt();
108 //System.out.println("Receiver received length: " + maxlen);
109 // Receive until maxlen
110 if (maxlen>BUFFSIZE) {
111 System.out.println("IoTSocketClient/Server: Sending more bytes then will fit in buffer! Number of bytes: " + maxlen);
112 // Allocate a bigger array when needed
114 while (newLen < maxlen) // Shift until we get a new buffer size that's bigger than maxLen (basically power of 2)
115 newLen = newLen << 1;
116 System.out.println("IoTSocketClient/Server: Allocating a bigger buffer now with size: " + newLen);
118 data = new byte[BUFFSIZE];
120 val = new byte[maxlen];
121 while (totalbytes < maxlen)
123 numbytes = input.read(data);
124 // copy the bytes into the result buffer
125 for (i=totalbytes; i<totalbytes+numbytes; i++)
126 val[i] = data[i-totalbytes];
127 totalbytes += numbytes;
129 // we now send an acknowledgement to the server to let them
131 //System.out.println("Receiver about to send ACK!");
133 //System.out.println("Receiver about to receive ACK!\n\n");
141 * Close socket connection
143 public void close() throws IOException
152 public synchronized void sendAck() throws IOException
164 public synchronized void receiveAck() throws IOException
167 ack = (int) input.read();
174 public void setSoTimeout(int timeout) throws SocketException {
176 sock.setSoTimeout(timeout);