|
rllib
1
|
00001 /*************************************************************************** 00002 rludpsocket.cpp - description 00003 ------------------- 00004 begin : Tue Apr 03 2007 00005 copyright : (C) 2007 by Rainer Lehrig 00006 email : lehrig@t-online.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as * 00013 * published by the Free Software Foundation * 00014 * * 00015 ***************************************************************************/ 00016 #include "rludpsocket.h" 00017 #include "rlcutil.h" 00018 #include <stdio.h> 00019 #include <string.h> 00020 00021 rlIpAdr::rlIpAdr() 00022 { 00023 rlwsa(); // init sockets on windows 00024 memset(&address,0,sizeof(address)); 00025 } 00026 00027 rlIpAdr::~rlIpAdr() 00028 { 00029 } 00030 00031 int rlIpAdr::setAdr(const char *adr, int port) 00032 { 00033 if(port < 0 || port >= 256*256) return -1; 00034 struct in_addr IpAddress; 00035 struct hostent *host; 00036 00037 memset(&IpAddress,0,sizeof(IpAddress)); 00038 memset(&address,0,sizeof(address)); 00039 00040 host = gethostbyname(adr); 00041 if(host == NULL) 00042 { 00043 // See if the host is specified in "dot address" form 00044 IpAddress.s_addr = inet_addr(adr); 00045 if(IpAddress.s_addr == INADDR_NONE) 00046 { 00047 ::printf("rlIpAdr::setAdr() could not gethostbyname(%s)\n",adr); 00048 return -1; 00049 } 00050 } 00051 else 00052 { 00053 memcpy(&IpAddress,host->h_addr,host->h_length); 00054 } 00055 00056 address.sin_family = AF_INET; 00057 address.sin_port = htons((short) port); 00058 address.sin_addr = IpAddress; 00059 00060 return 0; 00061 } 00062 00063 int rlIpAdr::operator==(rlIpAdr &address1) 00064 { 00065 if(address.sin_family != address1.address.sin_family) return 0; 00066 if(memcmp(&address.sin_addr,&address1.address.sin_addr,sizeof(address.sin_addr)) == 0) return 1; 00067 return 0; 00068 } 00069 00070 //################################################################### 00071 00072 rlUdpSocket::rlUdpSocket(int _debug) 00073 { 00074 debug = _debug; 00075 if(debug) ::printf("rlUdpSocket() constructor\n"); 00076 rlwsa(); // init sockets on windows 00077 readflag = writeflag = 0; 00078 s = socket(AF_INET,SOCK_DGRAM,0); 00079 if(s < 0) 00080 { 00081 s = -1; 00082 ::printf("rlUdpSocket::rlUdpSocket could not get socket\n"); 00083 } 00084 } 00085 00086 rlUdpSocket::~rlUdpSocket() 00087 { 00088 if(s > 0) 00089 { 00090 #ifdef RLWIN32 00091 closesocket(s); 00092 #else 00093 close(s); 00094 #endif 00095 } 00096 } 00097 00098 int rlUdpSocket::setSockopt(int opt) 00099 { 00100 const int on = 1; 00101 if(s == -1) return -1; 00102 // set socket options 00103 #ifdef RLWIN32 00104 return setsockopt(s,SOL_SOCKET,opt,(const char *) &on,sizeof(on)); 00105 #else 00106 return setsockopt(s,SOL_SOCKET,opt,&on,sizeof(on)); 00107 #endif 00108 } 00109 00110 int rlUdpSocket::setSockopt(int level, int optname, void *optval, int optlen) 00111 { 00112 if(s == -1) return -1; 00113 if(optlen <= 0) return -1; 00114 // set socket options 00115 #ifdef RLWIN32 00116 return setsockopt(s,level,optname,(const char *) &optval,optlen); 00117 #else 00118 return setsockopt(s,level,optname,optval,optlen); 00119 #endif 00120 } 00121 00122 int rlUdpSocket::bind(int port) 00123 { 00124 if(port < 0 || port >= 256*256) return -1; 00125 00126 memset(&address,0,sizeof(address)); 00127 address.sin_family = AF_INET; 00128 address.sin_port = htons((short) port); 00129 address.sin_addr.s_addr = htonl(INADDR_ANY); 00130 // bind socket 00131 if(::bind(s, (sockaddr *) &address, sizeof(address)) < 0) 00132 { 00133 ::printf("rlUdpSocket::setAdr() bind() failed port=%d\n", port); 00134 return -1; 00135 } 00136 return 0; 00137 } 00138 00139 int rlUdpSocket::select(int timeout) 00140 { 00141 if(timeout < 0) return -1; 00142 struct timeval timout; 00143 fd_set wset,rset,eset; 00144 int ret,maxfdp1; 00145 00146 /* setup sockets to read */ 00147 maxfdp1 = s+1; 00148 FD_ZERO(&rset); 00149 FD_SET (s,&rset); 00150 FD_ZERO(&wset); 00151 FD_ZERO(&eset); 00152 timout.tv_sec = timeout / 1000; 00153 timout.tv_usec = (timeout % 1000) * 1000; 00154 00155 ret = ::select(maxfdp1,&rset,&wset,&eset,&timout); 00156 if(ret == 0) return 0; /* timeout */ 00157 return 1; 00158 } 00159 00160 int rlUdpSocket::recvfrom(void *buf, int maxlen, rlIpAdr *source, int timeout) 00161 { 00162 int ret, len; 00163 00164 if(timeout >= 0) 00165 { 00166 ret = select(timeout); 00167 if(ret != 1) return -1; // timeout 00168 } 00169 if(debug) ::printf("rlUdpSocket()::recvfrom() ...\n"); 00170 len = sizeof(source->address); 00171 #ifdef RLWIN32 00172 ret = ::recvfrom(s, (char *) buf, maxlen, readflag, 00173 (struct sockaddr *) &source->address, (int FAR *) &len); 00174 #endif 00175 #ifdef RLUNIX 00176 ret = ::recvfrom(s, buf, maxlen, readflag, 00177 (struct sockaddr *) &source->address, (socklen_t *) &len); 00178 #endif 00179 #ifdef __VMS 00180 ret = ::recvfrom(s, buf, maxlen, readflag, 00181 (struct sockaddr *) &source->address, (size_t *) &len); 00182 #endif 00183 if(ret < 0) 00184 { 00185 ::printf("ERROR: rlUdpSocket::read()\n"); 00186 return -2; 00187 } 00188 if(debug) 00189 { 00190 unsigned char *cbuf = (unsigned char *) buf; 00191 ::printf("rlUdpSocket()::recvfrom() ret=%d data=[0x%x",ret,cbuf[0]); 00192 for(int i=1; i<ret; i++) ::printf(",0x%x",cbuf[i]); 00193 ::printf("]\n"); 00194 } 00195 return ret; 00196 } 00197 00198 int rlUdpSocket::sendto(const void *buf, int len, rlIpAdr *dest) 00199 { 00200 #ifdef RLWIN32 00201 int ret = ::sendto(s, (const char *) buf, len, writeflag, 00202 (struct sockaddr *) &dest->address, sizeof(struct sockaddr_in)); 00203 #else 00204 int ret = ::sendto(s, buf, len, writeflag, 00205 (struct sockaddr *) &dest->address, sizeof(struct sockaddr_in)); 00206 #endif 00207 if(ret < 0) ::printf("ERROR: rlUdpSocket::sendto()\n"); 00208 if(debug) 00209 { 00210 unsigned char *cbuf = (unsigned char *) buf; 00211 ::printf("rlUdpSocket()::sendto() ret=%d data=[0x%x",ret,cbuf[0]); 00212 for(int i=1; i<ret; i++) ::printf(",0x%x",cbuf[i]); 00213 ::printf("]\n"); 00214 } 00215 return ret; 00216 } 00217 00218 int rlUdpSocket::printf(rlIpAdr *dest, const char *format, ...) 00219 { 00220 int ret; 00221 char message[rl_PRINTF_LENGTH]; // should be big enough 00222 00223 va_list ap; 00224 va_start(ap,format); 00225 ret = rlvsnprintf(message, rl_PRINTF_LENGTH - 1, format, ap); 00226 va_end(ap); 00227 if(ret < 0) return ret; 00228 return sendto(message,strlen(message)+1,dest); 00229 } 00230 00231 //#define TESTING 00232 #ifdef TESTING 00233 00234 int main(int ac, char **av) 00235 { 00236 int ret; 00237 char buf[1024]; 00238 rlUdpSocket udp; 00239 rlIpAdr dest; 00240 dest.setAdr("localhost",5050); 00241 00242 if(ac == 2) // client 00243 { 00244 while(1) 00245 { 00246 sleep(1); 00247 ret = udp.sendto(av[1], strlen(av[1])+1, &dest); 00248 if(ret > 0) 00249 { 00250 printf("udp.sendto(%s) ret=%d\n",av[1],ret); 00251 } 00252 else printf("udp.sendto() failed\n"); 00253 } 00254 } 00255 else // server 00256 { 00257 rlIpAdr source; 00258 ret = udp.bind(5050); 00259 while(1) 00260 { 00261 if((ret = udp.recvfrom(buf,sizeof(buf), &source, 1000)) > 0) 00262 { 00263 printf("udp.recvfrom(%s) ret=%d\n",buf,ret); 00264 if(dest == source) printf("dest==source\n"); 00265 else printf("dest!=source\n"); 00266 } 00267 else printf("udp.recvfrom() failed or timeout\n"); 00268 } 00269 } 00270 return 0; 00271 } 00272 00273 #endif
1.7.5.1