Added UDP sending support to socket library.
This commit is contained in:
parent
6420c42ac5
commit
773234f231
2 changed files with 127 additions and 0 deletions
107
lib/socket.cpp
107
lib/socket.cpp
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
20
lib/socket.h
20
lib/socket.h
|
@ -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.
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue