1 /** Class IoTSocket is a base class for IoTSocketServer.cpp
2 * and IoTSocketClient.cpp that provide interfaces to connect
3 * to either Java or C++ socket endpoint
5 * Adapted from Java/C++ socket implementation
7 * @see <a href="https://www.keithv.com/software/socket/</a>
9 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
13 #ifndef _IOTSOCKET_HPP__
14 #define _IOTSOCKET_HPP__
16 // Adds in the send/recv acks after each message.
19 static const int SOCKET_BUFF_SIZE = 64000;
20 // Before, it was too short as we were just using 1 byte to receive the length
21 // Now, we allocate 4 bytes (a size of integer) to receive the message length
22 static const int MSG_LEN_SIZE = 4;
28 #include <sys/types.h>
30 #include <netinet/in.h>
32 #include <sys/socket.h>
36 #include "IoTRMIUtil.hpp"
38 // Duplicated from winsock2.h
39 #define SD_RECEIVE 0x00
46 IoTSocket(int iPort, bool* pResult);
49 bool close(); // Close the socket
50 bool sendBytes(char* pVals, int _iLen); // Send a set of bytes
51 char* receiveBytes(char* pVals, int* len); // Receive a set of bytes
54 int m_iPort; // Port I'm listening on
55 int m_iSock; // Socket connection
56 struct sockaddr_in m_addrRemote; // Connector's address information
57 double* m_pBuffer; // Reuse the same memory for buffer
66 IoTSocket::IoTSocket(int iPort, bool* pResult) {
72 // Allocate our temporary buffers that are used to convert data types
73 m_pBuffer = (double *) malloc(sizeof(double) * SOCKET_BUFF_SIZE);
75 perror("IoTSocket: Failed to malloc buffer!");
83 IoTSocket::~IoTSocket() {
92 // Send bytes over the wire
93 bool IoTSocket::sendBytes(char* pVals, int iLen) {
96 char size[MSG_LEN_SIZE];
97 // Convert int to byte array and fix endianness
98 IoTRMIUtil::intToByteArray(iLen, size);
100 if (send(m_iSock, size, MSG_LEN_SIZE, 0) == -1) {
101 perror("IoTSocket: Send size error!");
105 if (send(m_iSock, (char *) pVals, iLen, 0) == -1) {
106 perror("IoTSocket: Send bytes error!");
120 // Receive bytes, returns number of bytes received
121 // Generate an array of char on the heap and return it
122 char* IoTSocket::receiveBytes(char* pVals, int* len)
133 char size[MSG_LEN_SIZE];
135 while ((iTotal < 1) && (iResult != -1)) {
136 iResult = recv(m_iSock, size, MSG_LEN_SIZE, 0);
140 perror("IoTSocket: Receive size error!");
143 // Convert byte to int array based on correct endianness
145 IoTRMIUtil::byteArrayToInt(&iLen, size);
147 // To be returned from this method...
149 pVals = new char[iLen];
150 pTemp = (char *) m_pBuffer;
151 // We receiving the incoming ints one byte at a time.
153 if ((iNumBytes = recv(m_iSock, pTemp, SOCKET_BUFF_SIZE, 0)) == -1) {
154 perror("IoTSocket: Receive error!");
157 for (i = 0; i < iNumBytes; i++) {
161 iTotalBytes += iNumBytes;
162 if (iTotalBytes == iLen)
175 // Shut down the socket
176 bool IoTSocket::close()
178 if (shutdown(m_iSock, SD_BOTH) == -1) {
179 perror("IoTSocket: Close error!");
187 // Receive a short ack from the client
188 bool IoTSocket::receiveAck()
193 while ((iTotal < 1) && (iResult != -1)) {
195 iResult = recv(m_iSock, temp, 1, 0);
200 perror("IoTSocket: ReceiveAck error!");
208 // Send a short ack to the client
209 bool IoTSocket::sendAck()
214 if (send(m_iSock, temp, 1, 0) == -1)