Remove dynamic exceptions
[anna.git] / source / comm / DatagramSocket.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <sys/uio.h>
12
13 #include <anna/core/tracing/Logger.hpp>
14 #include <anna/core/DataBlock.hpp>
15 #include <anna/config/defines.hpp>
16 #include <anna/core/functions.hpp>
17
18 #include <anna/comm/DatagramSocket.hpp>
19
20 using namespace std;
21 using namespace anna;
22
23 comm::DatagramSocket::DatagramSocket(const comm::DatagramSocket::Mode mode, const comm::INetAddress& address, comm::TransportFactory* transportFactory) :
24       comm::ClientSocket(transportFactory, comm::Socket::Domain::Inet, comm::Socket::Type::Datagram),
25       a_mode(mode) {
26    if (mode == ReadOnly)
27       a_localAccessPoint = address;
28    else
29       a_remoteAccessPoint = address;
30 }
31
32 void comm::DatagramSocket::connect()
33 noexcept(false) {
34    Guard guard(*this, "comm::DatagramSocket::connect");
35    anna_socket_assert(isConnected() == true, "Already connected");
36
37    if (Socket::isOpened() == false) {
38       Socket::open();
39       getSocketOptions();
40       setBlockingMode(false);
41    }
42
43    // Hace el bind a la localAddress.
44    if (a_mode == ReadOnly && Socket::isBound() == false)
45       Socket::bind();
46
47    activate(Status::Connected);
48    LOGDEBUG(
49       string msg("comm::DatagramSocket::connect | ");
50       msg += asString();
51       Logger::debug(msg, ANNA_FILE_LOCATION);
52    );
53 }
54
55 void comm::DatagramSocket::do_write(const DataBlock& message)
56 noexcept(false) {
57    sockaddr* s(NULL);
58    int len(0);
59    a_remoteAccessPoint.translate(*this, s, len);
60    int r;
61    anna_signal_shield(r, sendto(Socket::a_fd, message.getData(), message.getSize(), 0, s, len));
62
63    if (r < 0) {
64       const int xerrno = errno;
65       string msg(asString());
66       msg += " | Cannot be sent";
67       throw RuntimeException(msg, xerrno, ANNA_FILE_LOCATION);
68    }
69
70    LOGDEBUG(
71       string msg("comm::DatagramSocket::do_write | ");
72       msg += asString();
73       msg += functions::asText(" | Sent: ", message);
74       Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
75    );
76 }
77
78 int comm::DatagramSocket::do_read(const char* data, const int maxSize)
79 noexcept(false) {
80    int result;
81    anna_signal_shield(result, recvfrom(Socket::a_fd, (void*) data, maxSize, 0, (sockaddr*) NULL, NULL));
82
83    if (result < 0) {
84       const int xerrno = errno;
85       string msg(asString());
86       msg += " | Cannot be received";
87       throw RuntimeException(msg, xerrno, ANNA_FILE_LOCATION);
88    }
89
90    LOGDEBUG(
91       string msg("comm::DatagramSocket::do_read | ");
92       msg += asString();
93       msg += functions::asText(" | N-bytes", result);
94       msg += functions::asText(" | Received: ", DataBlock(data, result, false));
95       Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
96    );
97    return result;
98 }
99
100