Adding last version of iotruntime and iotinstaller; preparing to extend IoTMaster...
[iot2.git] / iotjava / iotrmi / C++ / IoTSocketServer.hpp
1 /** Class IoTSocketServer is a communication class
2  *  that provides interfaces to connect to either
3  *  Java or C++ socket endpoint. It inherits the
4  *  methods from IoTSocket.
5  *  <p>
6  *  Adapted from Java/C++ socket implementation
7  *  by Keith Vertanen
8  *  @see        <a href="https://www.keithv.com/software/socket/</a>
9  *
10  * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
11  * @version     1.0
12  * @since       2016-08-17
13  */
14 #ifndef _IOTSOCKETSERVER_HPP__
15 #define _IOTSOCKETSERVER_HPP__
16
17 #include "IoTSocket.hpp"
18
19 #define BACKLOG 10      // How many pending connections queue will hold 
20
21 class IoTSocketServer : public IoTSocket
22 {
23   public:
24                 IoTSocketServer(int iPort, bool* pResult);
25
26                 bool                            connect();                                                      // Accept a new connection
27
28         protected:              
29                 bool                            m_bReverse;                                                     // Am I reversing byte order or not?
30                 int                                     m_iListen;                                                      // Descriptor we are listening on
31                 struct sockaddr_in      m_addrMe;                                                       // My address information
32 };
33
34
35 // Constructor
36 IoTSocketServer::IoTSocketServer(int iPort, bool* pResult) :
37         IoTSocket(iPort, pResult) {
38
39         m_iListen               = -1;
40
41         if (pResult)
42                 *pResult = false;
43
44         if ((m_iListen = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
45         {
46                 perror("IoTSocketServer: Socket error!");
47                 return;
48         }
49
50         m_addrMe.sin_family                     = AF_INET;          // Host byte order 
51         m_addrMe.sin_port                       = htons(m_iPort);       // Short, network byte order 
52         m_addrMe.sin_addr.s_addr        = INADDR_ANY;           // Auto-fill with my IP 
53         memset(&(m_addrMe.sin_zero), 0, 8);                             // Zero the rest of the struct 
54
55         if (bind(m_iListen, (struct sockaddr *) &m_addrMe, sizeof(struct sockaddr)) == -1) 
56         {
57                 // Note, this can fail if the server has just been shutdown and not enough time has elapsed.
58                 // See: http://www.developerweb.net/forum/showthread.php?t=2977 
59                 perror("IoTSocketServer: Bind error!");
60                 return;
61         }
62
63         if (listen(m_iListen, BACKLOG) == -1) 
64         {
65                 perror("IoTSocketServer: Listen error!");
66                 return;
67         }
68
69         if (pResult)
70                 *pResult = true;
71 }
72
73
74 // Wait for somebody to connect to us on our port.
75 bool IoTSocketServer::connect()
76 {
77         socklen_t iSinSize = (socklen_t) sizeof(struct sockaddr_in);
78
79         if ((m_iSock = accept(m_iListen, (struct sockaddr *) &m_addrRemote, &iSinSize)) == -1) 
80         {
81                 perror("IoTSocketServer: Accept connection error!");
82                 return false;
83         }
84         // The client sends us an int to indicate if we should
85         // be reversing byte order on this connection.  The client 
86         // is sending 0 or 1, so a reversed 0 still looks
87         // like a 0, no worries mate!
88         char temp[1];
89         int iTotal = 0;
90         int iResult = 0;
91         while ((iTotal < 1) && (iResult != -1))
92         {
93                 iResult = recv(m_iSock, temp, 1, 0);
94                 iTotal += iResult;
95         }
96         if (iResult == -1)
97         {
98                 perror("IoTSocketServer: Receive data error!");
99                 return false;
100         }
101
102         int iVal = temp[0];
103
104         if (iVal == 0) 
105                 m_bReverse = false;
106         else 
107                 m_bReverse = true;
108
109         return true;
110 }
111
112 #endif