Added UDP sending support to socket library.

This commit is contained in:
Thulinma 2014-02-03 16:50:37 +01:00
parent 6420c42ac5
commit 773234f231
2 changed files with 127 additions and 0 deletions

View file

@ -9,6 +9,7 @@
#include <poll.h> #include <poll.h>
#include <netdb.h> #include <netdb.h>
#include <sstream> #include <sstream>
#include <cstdlib>
#ifdef __FreeBSD__ #ifdef __FreeBSD__
#include <netinet/in.h> #include <netinet/in.h>
@ -896,3 +897,109 @@ bool Socket::Server::connected() const{
int Socket::Server::getSocket(){ int Socket::Server::getSocket(){
return sock; return sock;
} }
/// Create a new UDP Socket.
/// \param nonblock Whether the socket should be nonblocking.
Socket::UDPConnection::UDPConnection(bool nonblock){
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock == -1){
sock = socket(AF_INET, SOCK_DGRAM, 0);
}
if (sock == -1){
DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));
}
up = 0;
down = 0;
destAddr = 0;
destAddr_size = 0;
if (nonblock){
setBlocking(!nonblock);
}
} //Socket::UDPConnection UDP Contructor
Socket::UDPConnection::UDPConnection(const UDPConnection & o){
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock == -1){
sock = socket(AF_INET, SOCK_DGRAM, 0);
}
if (sock == -1){
DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));
}
up = 0;
down = 0;
if (o.destAddr && o.destAddr_size){
destAddr = malloc(o.destAddr_size);
if (destAddr){
memcpy(destAddr, o.destAddr, o.destAddr_size);
}
}else{
destAddr = 0;
destAddr_size = 0;
}
}
Socket::UDPConnection::~UDPConnection(){
if (sock != -1){
errno = EINTR;
while (::close(sock) != 0 && errno == EINTR){
}
sock = -1;
}
if (destAddr){
free(destAddr);
destAddr = 0;
}
}
void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){
destAddr = malloc(sizeof(struct sockaddr_in6));
if (destAddr){
destAddr_size = sizeof(struct sockaddr_in6);
memset(destAddr, 0, destAddr_size);
((struct sockaddr_in6*)destAddr)->sin6_family = AF_INET6;
((struct sockaddr_in6*)destAddr)->sin6_port = htons(port);
if(inet_pton(AF_INET6, destIp.c_str(), &(((struct sockaddr_in6*)destAddr)->sin6_addr)) == 1){
return;
}
free(destAddr);
destAddr = 0;
}
destAddr = malloc(sizeof(struct sockaddr_in));
if (destAddr){
destAddr_size = sizeof(struct sockaddr_in);
memset(destAddr, 0, destAddr_size);
((struct sockaddr_in*)destAddr)->sin_family = AF_INET;
((struct sockaddr_in*)destAddr)->sin_port = htons(port);
if(inet_pton(AF_INET, destIp.c_str(), &(((struct sockaddr_in*)destAddr)->sin_addr)) == 1){
return;
}
free(destAddr);
destAddr = 0;
}
DEBUG_MSG(DLVL_FAIL, "Could not set destination for UDP socket: %s:%d", destIp.c_str(), port);
}//Socket::UDPConnection SetDestination
void Socket::UDPConnection::setBlocking(bool blocking){
if (sock >= 0){
setFDBlocking(sock, blocking);
}
}
void Socket::UDPConnection::SendNow(const std::string & data){
SendNow(data.c_str(), data.size());
}
void Socket::UDPConnection::SendNow(const char* data){
int len = strlen(data);
SendNow(data, len);
}
void Socket::UDPConnection::SendNow(const char * data, size_t len){
if (len < 1){return;}
int r = sendto(sock, data, len, 0, (sockaddr*)destAddr, destAddr_size);
if (r > 0){
up += r;
}else{
DEBUG_MSG(DLVL_FAIL, "Could not send UDP data through %d: %s", sock, strerror(errno));
}
}

View file

@ -118,5 +118,25 @@ namespace Socket {
void drop(); ///< Close connection without shutdown. void drop(); ///< Close connection without shutdown.
int getSocket(); ///< Returns internal socket number. int getSocket(); ///< Returns internal socket number.
}; };
class UDPConnection{
private:
int sock; ///< Internally saved socket number.
std::string remotehost;///< Stores remote host address
void * destAddr;
unsigned int destAddr_size;
unsigned int up;
unsigned int down;
public:
UDPConnection(const UDPConnection & o); ///< Copy constructor
UDPConnection(bool nonblock = false); ///< Create new UDP socket
~UDPConnection();
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
void SetDestination(std::string hostname, uint32_t port); ///< Sets the hostname and port destination for this UDP socket.
void Close();///< Closes the local socket
void SendNow(const std::string & data); ///< Will not buffer anything but always send right away. Blocks.
void SendNow(const char * data); ///< Will not buffer anything but always send right away. Blocks.
void SendNow(const char * data, size_t len); ///< Will not buffer anything but always send right away. Blocks.
};
} }