Subversion Repositories HomeAutomation

Rev

Rev 1122 | Rev 1203 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1122 Rev 1124
Line 75... Line 75...
75
            loop = receiveData();
75
            loop = receiveData();
76
        }
76
        }
77
    }
77
    }
78
    catch (SocketException *e)
78
    catch (SocketException *e)
79
    {
79
    {
-
 
80
        cout << "DEBUG: socket got an exception: " << e->getDescription() << endl;
80
        // Something bad happend and we can not continue
81
        // Something bad happend and we can not continue
81
        eventAdd(SocketEvent::TYPE_CONNECTION_DIED, e->getDescription());
82
        eventAdd(SocketEvent::TYPE_CONNECTION_DIED, e->getDescription());
82
    }
83
    }
83
 
84
 
84
    // Clean up socket if we would want to restart
85
    // Clean up socket if we would want to restart
Line 88... Line 89...
88
bool AsyncSocket::receiveData()
89
bool AsyncSocket::receiveData()
89
{
90
{
90
    char buffer[MAXBUFFER + 1];
91
    char buffer[MAXBUFFER + 1];
91
    memset(buffer, 0, MAXBUFFER + 1);
92
    memset(buffer, 0, MAXBUFFER + 1);
92
 
93
 
-
 
94
    //cout << "recv start" << endl;
93
    int status = ::recv(mySocket, buffer, MAXBUFFER, 0);
95
    int status = ::recv(mySocket, buffer, MAXBUFFER, 0);
-
 
96
    //cout << "recv end" << endl;
94
 
97
   
95
    if (status == -1)
98
    if (status == -1)
96
    {
99
    {
97
        switch (errno)
100
        switch (errno)
98
        {
101
        {
99
            case EAGAIN:
102
            case EAGAIN:
Line 111... Line 114...
111
            case EINTR:
114
            case EINTR:
112
            throw new SocketException("The receive was interrupted by delivery of a signal before any data were available; see signal(7).");
115
            throw new SocketException("The receive was interrupted by delivery of a signal before any data were available; see signal(7).");
113
 
116
 
114
            case EINVAL:
117
            case EINVAL:
115
            throw new SocketException("Invalid argument passed.");
118
            throw new SocketException("Invalid argument passed.");
116
 
119
 
117
            case ENOMEM:
120
            case ENOMEM:
118
            throw new SocketException("Could not allocate memory for recvmsg().");
121
            throw new SocketException("Could not allocate memory for recvmsg().");
119
 
122
 
120
            case ENOTCONN:
123
            case ENOTCONN:
121
            throw new SocketException("The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).");
124
            throw new SocketException("The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).");
122
 
125
 
123
            case ENOTSOCK:
126
            case ENOTSOCK:
124
            throw new SocketException("The argument s does not refer to a socket.");
127
            throw new SocketException("The argument s does not refer to a socket.");
125
 
128
 
126
            case ECONNRESET:
129
            case ECONNRESET:
127
            eventAdd(SocketEvent::TYPE_CONNECTION_RESET);
130
            eventAdd(SocketEvent::TYPE_CONNECTION_RESET);
128
 
131
 
129
            // If we have automatic reconnect we want to start it now
132
            // If we have automatic reconnect we want to start it now
130
            if (myReconnectTimeout == 0)
133
            if (myReconnectTimeout == 0)
131
            {
134
            {
132
                reconnectLoop();
135
                reconnectLoop();
133
            }
136
            }
134
            else
137
            else
135
            {
138
            {
136
                // Otherwise we would like to end the main loop
139
                // Otherwise we would like to end the main loop
137
                return false;
140
                return false;
138
            }
141
            }
139
            break;
142
            break;
140
 
143
 
141
            default:
144
            default:
142
            throw new SocketException("Unknow exception: " + itos(errno));
145
            throw new SocketException("Unknow exception: " + itos(errno));
143
            break;
146
            break;
144
        }
147
        }
145
    }
148
    }
Line 218... Line 221...
218
{
221
{
219
    create();
222
    create();
220
 
223
 
221
    myAddressStruct.sin_family = AF_INET;
224
    myAddressStruct.sin_family = AF_INET;
222
    myAddressStruct.sin_addr.s_addr = INADDR_ANY;
225
    myAddressStruct.sin_addr.s_addr = INADDR_ANY;
223
    myAddressStruct.sin_port = htons(myPort);
226
    myAddressStruct.sin_port = htons(myPort);
224
 
227
 
225
    int status = ::bind(mySocket, (struct sockaddr *)&myAddressStruct, sizeof(myAddressStruct));
228
    int status = ::bind(mySocket, (struct sockaddr *)&myAddressStruct, sizeof(myAddressStruct));
226
 
229
 
227
    if (status == -1)
230
    if (status == -1)
228
    {
231
    {
229
        silentClose();
232
        silentClose();
230
        switch (errno)
233
        switch (errno)
231
        {
234
        {
232
            case EACCES:
235
            case EACCES:
233
            throw new SocketException("The address is protected, and the user is not the superuser.");
236
            throw new SocketException("The address is protected, and the user is not the superuser.");
234
 
237
 
235
            case EADDRINUSE:
238
            case EADDRINUSE:
236
            throw new SocketException("The given address is already in use.");
239
            throw new SocketException("The given address is already in use.");
237
 
240
 
Line 250... Line 253...
250
            case EADDRNOTAVAIL:
253
            case EADDRNOTAVAIL:
251
            throw new SocketException("A nonexistent interface was requested or the requested address was not local.");
254
            throw new SocketException("A nonexistent interface was requested or the requested address was not local.");
252
 
255
 
253
            case EFAULT:
256
            case EFAULT:
254
            throw new SocketException("addr points outside the user's accessible address space.");
257
            throw new SocketException("addr points outside the user's accessible address space.");
255
 
258
 
256
            //case EINVAL:
259
            //case EINVAL:
257
            //throw new SocketException("The addrlen is wrong, or the socket was not in the AF_UNIX family.");
260
            //throw new SocketException("The addrlen is wrong, or the socket was not in the AF_UNIX family.");
258
 
261
 
259
            case ELOOP:
262
            case ELOOP:
260
            throw new SocketException("Too many symbolic links were encountered in resolving addr.");
263
            throw new SocketException("Too many symbolic links were encountered in resolving addr.");
261
 
264
 
262
            case ENAMETOOLONG:
265
            case ENAMETOOLONG:
263
            throw new SocketException("addr is too long.");
266
            throw new SocketException("addr is too long.");
264
 
267
 
265
            case ENOENT:
268
            case ENOENT:
266
            throw new SocketException("The file does not exist.");
269
            throw new SocketException("The file does not exist.");
267
 
270
 
268
            case ENOMEM:
271
            case ENOMEM:
269
            throw new SocketException("Insufficient kernel memory was available.");
272
            throw new SocketException("Insufficient kernel memory was available.");
270
 
273
 
271
            case ENOTDIR:
274
            case ENOTDIR:
272
            throw new SocketException("A component of the path prefix is not a directory.");
275
            throw new SocketException("A component of the path prefix is not a directory.");
273
 
276
 
274
            case EROFS:
277
            case EROFS:
275
            throw new SocketException("The socket inode would reside on a read-only file system.");
278
            throw new SocketException("The socket inode would reside on a read-only file system.");
276
 
279
 
277
            default:
280
            default:
278
            throw new SocketException("Unknow exception: " + itos(errno));
281
            throw new SocketException("Unknow exception: " + itos(errno));
279
            break;
282
            break;
280
        }
283
        }
281
    }
284
    }
282
 
285
 
283
    status = ::listen(mySocket, MAXCONNECTIONS);
286
    status = ::listen(mySocket, MAXCONNECTIONS);
284
 
287
 
285
    if (status == -1)
288
    if (status == -1)
286
    {
289
    {
287
        silentClose();
290
        silentClose();
288
        switch (errno)
291
        switch (errno)
289
        {
292
        {
Line 296... Line 299...
296
            case ENOTSOCK:
299
            case ENOTSOCK:
297
            throw new SocketException("The argument sockfd is not a socket.");
300
            throw new SocketException("The argument sockfd is not a socket.");
298
 
301
 
299
            case EOPNOTSUPP:
302
            case EOPNOTSUPP:
300
            throw new SocketException("The socket is not of a type that supports the listen() operation.");
303
            throw new SocketException("The socket is not of a type that supports the listen() operation.");
301
 
304
 
302
            default:
305
            default:
303
            throw new SocketException("Unknow exception: " + itos(errno));
306
            throw new SocketException("Unknow exception: " + itos(errno));
304
            break;
307
            break;
305
        }
308
        }
306
    }
309
    }
307
}
310
}
308
 
311
 
309
bool AsyncSocket::accept(AsyncSocket* newSocket)
312
bool AsyncSocket::accept(AsyncSocket* newSocket)
310
{
313
{
311
    int addr_length = sizeof(myAddressStruct);
314
    int addr_length = sizeof(myAddressStruct);
312
    int socket = ::accept(mySocket, (sockaddr*)&myAddressStruct, (socklen_t*)&addr_length);
315
    int socket = ::accept(mySocket, (sockaddr*)&myAddressStruct, (socklen_t*)&addr_length);
313
 
316
 
314
    if (socket > 0)
317
    if (socket > 0)
315
    {
318
    {
316
        newSocket->setSocket(socket);
319
        newSocket->setSocket(socket);
317
        return true;
320
        return true;
318
    }
321
    }
319
 
322
 
320
    return false;
323
    return false;
321
}
324
}
322
 
325
 
323
void AsyncSocket::connect()
326
void AsyncSocket::connect()
324
{
327
{
325
    eventAdd(SocketEvent::TYPE_CONNECTING);
328
    eventAdd(SocketEvent::TYPE_CONNECTING);
326
 
329
 
327
    create();
330
    create();
328
 
331
 
329
    memset(&myAddressStruct, 0, sizeof(myAddressStruct));
332
    memset(&myAddressStruct, 0, sizeof(myAddressStruct));
330
 
333
 
331
    myAddressStruct.sin_family = AF_INET;
334
    myAddressStruct.sin_family = AF_INET;
332
    myAddressStruct.sin_port = htons(myPort);
335
    myAddressStruct.sin_port = htons(myPort);
333
 
336
 
334
    struct hostent *hptr = gethostbyname(myAddress.c_str());
337
    struct hostent *hptr = gethostbyname(myAddress.c_str());
335
    if (hptr == NULL)
338
    if (hptr == NULL)
336
    {
339
    {
337
        silentClose();
340
        silentClose();
338
        throw new SocketException("Connect: Could not resolv ip address");
341
        throw new SocketException("Connect: Could not resolv ip address");
339
    }
342
    }
340
 
343
 
341
    memcpy(&myAddressStruct.sin_addr, hptr->h_addr, hptr->h_length);
344
    memcpy(&myAddressStruct.sin_addr, hptr->h_addr, hptr->h_length);
342
 
345
 
343
    int status = ::connect(mySocket, (sockaddr*)&myAddressStruct, sizeof(myAddressStruct));
346
    int status = ::connect(mySocket, (sockaddr*)&myAddressStruct, sizeof(myAddressStruct));
344
 
347
 
345
    if (status == -1)
348
    if (status == -1)
346
    {
349
    {
347
        silentClose();
350
        silentClose();
Line 365... Line 368...
365
            case EALREADY:
368
            case EALREADY:
366
            throw new SocketException("The socket is non-blocking and a previous connection attempt has not yet been completed.");
369
            throw new SocketException("The socket is non-blocking and a previous connection attempt has not yet been completed.");
367
 
370
 
368
            case EBADF:
371
            case EBADF:
369
            throw new SocketException("The file descriptor is not a valid index in the descriptor table.");
372
            throw new SocketException("The file descriptor is not a valid index in the descriptor table.");
370
 
373
 
371
            case ECONNREFUSED:
374
            case ECONNREFUSED:
372
            throw new SocketException("No-one listening on the remote address.");
375
            throw new SocketException("No-one listening on the remote address.");
373
 
376
 
374
            case EFAULT:
377
            case EFAULT:
375
            throw new SocketException("The socket structure address is outside the user's address space.");
378
            throw new SocketException("The socket structure address is outside the user's address space.");
Line 402... Line 405...
402
 
405
 
403
void AsyncSocket::sendData(string data)
406
void AsyncSocket::sendData(string data)
404
{
407
{
405
    mySendMutex.lock();
408
    mySendMutex.lock();
406
 
409
 
407
    int status = ::send(mySocket, data.c_str(), data.size(), 0);
410
    int status = ::send(mySocket, data.c_str(), data.size(), MSG_NOSIGNAL);
408
//Logger::getInstance().add("Sent: \"" + data + "\" status was " + itos(status) + "\n");
411
//Logger::getInstance().add("Sent: \"" + data + "\" status was " + itos(status) + "\n");
409
    mySendMutex.unlock();
412
    mySendMutex.unlock();
410
 
413
 
411
    //Logger &log = Logger::getInstance();
414
    //Logger &log = Logger::getInstance();
412
    //log.add("Sent: \"" + data + "\" status was " + itos(status) + "\n");
415
    //log.add("Sent: \"" + data + "\" status was " + itos(status) + "\n");
Line 459... Line 462...
459
 
462
 
460
            case EOPNOTSUPP:
463
            case EOPNOTSUPP:
461
            throw new SocketException("Some bit in the flags argument is inappropriate for the socket type.");
464
            throw new SocketException("Some bit in the flags argument is inappropriate for the socket type.");
462
 
465
 
463
            case EPIPE:
466
            case EPIPE:
-
 
467
            close();
-
 
468
            stop();
464
            throw new SocketException("The local end has been shut down on a connection oriented socket. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.");
469
            //throw new SocketException("The local end has been shut down on a connection oriented socket. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.");
-
 
470
            break;
465
 
471
 
466
            default:
472
            default:
467
            throw new SocketException("Unknow exception: " + itos(errno));
473
            throw new SocketException("Unknow exception: " + itos(errno));
468
        }
474
        }
469
    }
475
    }