/* * */ #include #include #include #include #include #include #include /* close() */ #include /* 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; }