You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
3.7 KiB
184 lines
3.7 KiB
/*
|
|
*
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h> /* close() */
|
|
#include <string.h> /* memset() */
|
|
|
|
#include "udp.h"
|
|
|
|
char dnsip[NET_HOSTLEN];
|
|
|
|
int dns_filladdr (string host, string port, int ai_family, struct sockaddr_in *sAddr) {
|
|
struct addrinfo hints, *res;
|
|
int err;
|
|
|
|
/* we have to complete the sAddr struct */
|
|
bzero (&hints, sizeof (struct addrinfo));
|
|
hints.ai_family = ai_family;
|
|
hints.ai_socktype = SOCK_DGRAM;
|
|
|
|
if ((err = getaddrinfo (host.c_str(), port.c_str(), &hints, &res)) < 0) {
|
|
fprintf (stdout, "dns_filladdr (getaddrinfo):%s\n", gai_strerror (err));
|
|
return -1;
|
|
}
|
|
|
|
memcpy (sAddr, res->ai_addr, res->ai_addrlen);
|
|
freeaddrinfo (res);
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
UDPConnection::UDPConnection() {
|
|
sock = -1;
|
|
port = "";
|
|
writecnt = 0;
|
|
readcnt = 0;
|
|
};
|
|
|
|
|
|
UDPConnection::~UDPConnection() {
|
|
Close();
|
|
}
|
|
|
|
|
|
void UDPConnection::Close () {
|
|
if (sock > -1) close (sock);
|
|
sock = -1;
|
|
}
|
|
|
|
|
|
int UDPConnection::Listen(int port) {
|
|
struct sockaddr_in servAddr;
|
|
|
|
/* socket creation */
|
|
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
|
printf("%s: socket error: %s \n",__FUNCTION__, strerror(errno));
|
|
return 0;
|
|
}
|
|
|
|
/* bind local server port */
|
|
servAddr.sin_family = AF_INET;
|
|
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
servAddr.sin_port = htons(port);
|
|
if (bind (sock, (struct sockaddr *) &servAddr,sizeof(servAddr)) < 0) {
|
|
printf("%s: bind error: %s \n",__FUNCTION__, strerror(errno));
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
int UDPConnection::Listen(string port) {
|
|
return Listen (atoi(port.c_str()));
|
|
}
|
|
|
|
|
|
long int UDPConnection::ReadTimeout(string *source, char *buffer, long int len, int timeout) {
|
|
int i;
|
|
|
|
i = isData(timeout);
|
|
if (i > 0) {
|
|
return Read (source, buffer, len);
|
|
}
|
|
else
|
|
return i;
|
|
}
|
|
|
|
long int UDPConnection::Read(string *source, char *buffer, long int len) {
|
|
int n;
|
|
socklen_t addrlen;
|
|
sockaddr_in srcAddr;
|
|
|
|
if (!isListen()) return -1;
|
|
|
|
memset(buffer, 0x0, len);
|
|
|
|
addrlen = sizeof(srcAddr);
|
|
n = recvfrom(sock, buffer, len, 0, (sockaddr *) &srcAddr, &addrlen);
|
|
if(n<0) {
|
|
printf("%s: recvfrom error:%s\n",__FUNCTION__, strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
/* print received message */
|
|
char addr[NET_HOSTLEN];
|
|
snprintf (addr, NET_HOSTLEN, "%s:%d", inet_ntoa(srcAddr.sin_addr), ntohs(srcAddr.sin_port));
|
|
(*source) = (char*)addr;
|
|
|
|
return n;
|
|
}
|
|
|
|
|
|
long int UDPConnection::Send(string destaddr, char *buffer, long int len) {
|
|
int s;
|
|
int addrlen = sizeof (struct sockaddr_in);
|
|
sockaddr_in dstAddr;
|
|
string host;
|
|
string port;
|
|
|
|
if (!isListen()) {
|
|
/* socket creation */
|
|
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
|
printf("%s: socket error: %s \n",__FUNCTION__, strerror(errno));
|
|
return -1;
|
|
}
|
|
}
|
|
else s = sock;
|
|
|
|
int pos = destaddr.rfind(':', destaddr.length());
|
|
if (pos == -1) {
|
|
port = "NET_PORT";
|
|
host = destaddr;
|
|
}
|
|
else {
|
|
port = destaddr.substr (pos+1, destaddr.length() - pos);
|
|
host = destaddr.substr (0, pos);
|
|
}
|
|
|
|
dns_filladdr (host, port, PF_INET, &dstAddr);
|
|
if (sendto (s, buffer, len, 0, (sockaddr *) &dstAddr, addrlen) == -1) {
|
|
printf("%s: sendto error: %s \n",__FUNCTION__, strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
if (!isListen()) close (s);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int UDPConnection::isListen() {
|
|
return (sock != -1);
|
|
}
|
|
|
|
int UDPConnection::isData(int timeout) {
|
|
fd_set sockset;
|
|
struct timeval tval;
|
|
|
|
if (sock <= 0) {
|
|
printf ("isData:socket error\n");
|
|
return -1;
|
|
}
|
|
|
|
FD_ZERO (&sockset);
|
|
FD_SET (sock, &sockset);
|
|
tval.tv_sec = timeout / 1000;
|
|
tval.tv_usec = (timeout % 1000);
|
|
|
|
if (select (sock + 1, &sockset, NULL, NULL, &tval) >= 0) {
|
|
if (FD_ISSET (sock, &sockset)) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|