Thu, 11 Dec 2014 06:13:32 +0200
- fixed some problems with the ip address
| 5 | 1 | #include <sys/socket.h> |
| 2 | #include <sys/types.h> | |
| 3 | #include <sys/time.h> | |
| 4 | #include <netinet/in.h> | |
| 5 | #include <string.h> | |
| 6 | #include <fcntl.h> | |
| 6 | 7 | #include "udpsocket.h" |
| 5 | 8 | |
| 9 | // ----------------------------------------------------------------------------- | |
| 10 | // | |
| 11 | UDPSocket::UDPSocket() : | |
| 12 | m_socket (socket (AF_INET, SOCK_DGRAM, 0)) {} | |
| 13 | ||
| 14 | // ----------------------------------------------------------------------------- | |
| 15 | // | |
| 16 | UDPSocket::~UDPSocket() {} | |
| 17 | ||
| 18 | // ------------------------------------------------------------------------------------------------- | |
| 19 | // | |
| 20 | METHOD | |
| 21 | UDPSocket::set_blocking (bool a) -> bool | |
| 22 | { | |
| 23 | int flags = fcntl (m_socket, F_GETFL, 0); | |
| 24 | int newflags = (a ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)); | |
| 25 | ||
| 26 | if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0) | |
| 27 | { | |
| 28 | m_error = "Unable to set socket as non-blocking"; | |
| 29 | return false; | |
| 30 | } | |
| 31 | ||
| 32 | return true; | |
| 33 | } | |
| 34 | ||
| 35 | // ------------------------------------------------------------------------------------------------- | |
| 36 | // | |
| 37 | METHOD | |
| 38 | UDPSocket::bind (unsigned short port) -> bool | |
| 39 | { | |
| 40 | struct sockaddr_in svaddr; | |
| 41 | memset (&svaddr, 0, sizeof svaddr); | |
| 42 | svaddr.sin_family = AF_INET; | |
| 43 | svaddr.sin_port = htons (port); | |
| 44 | svaddr.sin_addr.s_addr = htonl (INADDR_ANY); | |
| 45 | ||
| 46 | if (::bind (m_socket, reinterpret_cast<struct sockaddr*> (&svaddr), sizeof svaddr) == -1) | |
| 47 | { | |
| 48 | m_error = String ("Couldn't bind to port ") + String::from_number (port); | |
| 49 | return false; | |
| 50 | } | |
| 51 | ||
| 52 | return true; | |
| 53 | } | |
| 54 | ||
| 55 | // ------------------------------------------------------------------------------------------------- | |
| 56 | // | |
| 57 | METHOD | |
| 58 | UDPSocket::read (Datagram& datagram) -> bool | |
| 59 | { | |
| 60 | sockaddr_in claddr; | |
| 61 | socklen_t socklen = sizeof claddr; | |
| 62 | static unsigned char packet[MAX_DATAGRAM_LENGTH]; | |
| 63 | int length = ::recvfrom (m_socket, packet, sizeof packet, 0, | |
| 64 | reinterpret_cast<struct sockaddr*> (&claddr), &socklen); | |
| 65 | ||
| 66 | if (length == -1) | |
| 67 | { | |
| 68 | // We got an error, though EWOULDBLOCK is silent as it means no packets recieved. | |
| 69 | if (errno != EWOULDBLOCK) | |
| 70 | m_error.sprintf ("recvfrom error: %s", strerror (errno));; | |
| 71 | ||
| 72 | return false; | |
| 73 | } | |
| 74 | ||
| 75 | datagram.from.host = ntohl (claddr.sin_addr.s_addr); | |
| 76 | datagram.from.port = ntohs (claddr.sin_port); | |
| 77 | datagram.data = Bytestream (packet, length); | |
| 78 | return true; | |
| 79 | } | |
| 80 | ||
| 81 | // ------------------------------------------------------------------------------------------------- | |
| 82 | // | |
| 83 | METHOD | |
| 84 | UDPSocket::send (const Bytestream& data, const IPAddress& addr) -> bool | |
| 85 | { | |
| 86 | struct sockaddr_in claddr = addr.to_sockaddr_in(); | |
| 87 | ||
| 88 | int res = ::sendto (m_socket, data.data(), data.written_length(), 0, | |
| 89 | reinterpret_cast<struct sockaddr*> (&claddr), sizeof claddr); | |
| 90 | ||
| 91 | if (res == -1) | |
| 92 | { | |
| 93 | m_error = String ("Unable to launch packet: ") + strerror (errno); | |
| 94 | return false; | |
| 95 | } | |
| 96 | ||
| 97 | return true; | |
| 98 | } |