Thu, 11 Dec 2014 07:18:11 +0200
- added huffman lib, now capable of initializing an rcon connection!
#include <sys/socket.h> #include <sys/types.h> #include <sys/time.h> #include <netinet/in.h> #include <string.h> #include <fcntl.h> #include "udpsocket.h" #include "../huffman/huffman.h" static unsigned char g_huffmanBuffer[131072]; // ----------------------------------------------------------------------------- // UDPSocket::UDPSocket() : m_socket (socket (AF_INET, SOCK_DGRAM, 0)) {} // ----------------------------------------------------------------------------- // UDPSocket::~UDPSocket() {} // ------------------------------------------------------------------------------------------------- // METHOD UDPSocket::set_blocking (bool a) -> bool { int flags = fcntl (m_socket, F_GETFL, 0); int newflags = (a ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK)); if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0) { m_error = "Unable to set socket as non-blocking"; return false; } return true; } // ------------------------------------------------------------------------------------------------- // METHOD UDPSocket::bind (unsigned short port) -> bool { struct sockaddr_in svaddr; memset (&svaddr, 0, sizeof svaddr); svaddr.sin_family = AF_INET; svaddr.sin_port = htons (port); svaddr.sin_addr.s_addr = htonl (INADDR_ANY); if (::bind (m_socket, reinterpret_cast<struct sockaddr*> (&svaddr), sizeof svaddr) == -1) { m_error = String ("Couldn't bind to port ") + String::from_number (port); return false; } return true; } // ------------------------------------------------------------------------------------------------- // METHOD UDPSocket::read (Datagram& datagram) -> bool { sockaddr_in claddr; socklen_t socklen = sizeof claddr; static unsigned char packet[MAX_DATAGRAM_LENGTH]; int length = ::recvfrom (m_socket, g_huffmanBuffer, sizeof packet, 0, reinterpret_cast<struct sockaddr*> (&claddr), &socklen); if (length == -1) { // We got an error, though EWOULDBLOCK is silent as it means no packets recieved. if (errno != EWOULDBLOCK) m_error.sprintf ("recvfrom error: %s", strerror (errno));; return false; } int decodedlength = sizeof g_huffmanBuffer; HUFFMAN_Decode (g_huffmanBuffer, packet, length, &decodedlength); datagram.from.host = ntohl (claddr.sin_addr.s_addr); datagram.from.port = ntohs (claddr.sin_port); datagram.data = Bytestream (packet, decodedlength); return true; } // ------------------------------------------------------------------------------------------------- // METHOD UDPSocket::send (const IPAddress& address, const Bytestream& data) -> bool { int encodedlength = sizeof g_huffmanBuffer; HUFFMAN_Encode (data.data(), g_huffmanBuffer, data.written_length(), &encodedlength); struct sockaddr_in claddr = address.to_sockaddr_in(); int res = ::sendto (m_socket, g_huffmanBuffer, encodedlength, 0, reinterpret_cast<struct sockaddr*> (&claddr), sizeof claddr); if (res == -1) { m_error = String ("Unable to launch packet: ") + strerror (errno); return false; } return true; }