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.
157 lines
3.0 KiB
157 lines
3.0 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 <stdlib.h>
|
|
#include <string.h> /* memset() */
|
|
#include <errno.h>
|
|
|
|
#include "UDPTCPNetwork.h"
|
|
|
|
UDP::UDP() {
|
|
sock = -1;
|
|
localport = -1;
|
|
writecnt = 0;
|
|
readcnt = 0;
|
|
};
|
|
|
|
|
|
UDP::~UDP() {
|
|
Close();
|
|
}
|
|
|
|
|
|
void UDP::Close () {
|
|
if (sock > -1) close (sock);
|
|
sock = -1;
|
|
}
|
|
|
|
|
|
int UDP::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
|
|
//
|
|
localport = port;
|
|
servAddr.sin_family = AF_INET;
|
|
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
servAddr.sin_port = htons(localport);
|
|
if (bind (sock, (struct sockaddr *) &servAddr,sizeof(servAddr)) < 0) {
|
|
printf("%s: bind error: %s \n",__FUNCTION__, strerror(errno));
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
long int UDP::ReadTimeout(string *source, char *buffer, long int len, int timeout_ms) {
|
|
int i;
|
|
|
|
i = IsData(timeout_ms);
|
|
if (i > 0) {
|
|
return Read (source, buffer, len);
|
|
}
|
|
else
|
|
return i;
|
|
}
|
|
|
|
long int UDP::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;
|
|
}
|
|
|
|
(*source) = inet_ntoa(srcAddr.sin_addr);
|
|
(*source) = (*source) + ":" + to_string (htons(srcAddr.sin_port));
|
|
return n;
|
|
}
|
|
|
|
|
|
long int UDP::Write(string destaddr, char *buffer, long int len) {
|
|
int s;
|
|
int addrlen = sizeof (struct sockaddr_in);
|
|
struct sockaddr_storage 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 UDP::IsListen() {
|
|
return (sock != -1);
|
|
}
|
|
|
|
int UDP::IsData(int timeout_ms) {
|
|
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_ms / 1000;
|
|
tval.tv_usec = (timeout_ms % 1000);
|
|
if (select (sock + 1, &sockset, NULL, NULL, &tval) >= 0) {
|
|
if (FD_ISSET (sock, &sockset)) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|