rllib  1
rludpsocket.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  rludpsocket.cpp - description
3  -------------------
4  begin : Tue Apr 03 2007
5  copyright : (C) 2007 by R. Lehrig
6  email : lehrig@t-online.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
13  * published by the Free Software Foundation *
14  * *
15  ***************************************************************************/
16 #include "rludpsocket.h"
17 #include "rlcutil.h"
18 #include <stdio.h>
19 #include <string.h>
20 
22 {
23  rlwsa(); // init sockets on windows
24  memset(&address,0,sizeof(address));
25 }
26 
28 {
29 }
30 
31 int rlIpAdr::setAdr(const char *adr, int port)
32 {
33  if(port < 0 || port >= 256*256) return -1;
34  struct in_addr IpAddress;
35  struct hostent *host;
36 
37  memset(&IpAddress,0,sizeof(IpAddress));
38  memset(&address,0,sizeof(address));
39 
40  host = gethostbyname(adr);
41  if(host == NULL)
42  {
43  // See if the host is specified in "dot address" form
44  IpAddress.s_addr = inet_addr(adr);
45  if(IpAddress.s_addr == INADDR_NONE)
46  {
47  ::printf("rlIpAdr::setAdr() could not gethostbyname(%s)\n",adr);
48  return -1;
49  }
50  }
51  else
52  {
53  memcpy(&IpAddress,host->h_addr,host->h_length);
54  }
55 
56  address.sin_family = AF_INET;
57  address.sin_port = htons((short) port);
58  address.sin_addr = IpAddress;
59 
60  return 0;
61 }
62 
64 {
65  if(address.sin_family != address1.address.sin_family) return 0;
66  if(memcmp(&address.sin_addr,&address1.address.sin_addr,sizeof(address.sin_addr)) == 0) return 1;
67  return 0;
68 }
69 
70 //###################################################################
71 
73 {
74  debug = _debug;
75  if(debug) ::printf("rlUdpSocket() constructor\n");
76  rlwsa(); // init sockets on windows
77  readflag = writeflag = 0;
78  s = socket(AF_INET,SOCK_DGRAM,0);
79  if(s < 0)
80  {
81  s = -1;
82  ::printf("rlUdpSocket::rlUdpSocket could not get socket\n");
83  }
84 }
85 
87 {
88  if(s > 0)
89  {
90 #ifdef RLWIN32
91  closesocket(s);
92 #else
93  close(s);
94 #endif
95  }
96 }
97 
99 {
100  const int on = 1;
101  if(s == -1) return -1;
102  // set socket options
103 #ifdef RLWIN32
104  return setsockopt(s,SOL_SOCKET,opt,(const char *) &on,sizeof(on));
105 #else
106  return setsockopt(s,SOL_SOCKET,opt,&on,sizeof(on));
107 #endif
108 }
109 
110 int rlUdpSocket::setSockopt(int level, int optname, void *optval, int optlen)
111 {
112  if(s == -1) return -1;
113  if(optlen <= 0) return -1;
114  // set socket options
115 #ifdef RLWIN32
116  return setsockopt(s,level,optname,(const char *) &optval,optlen);
117 #else
118  return setsockopt(s,level,optname,optval,optlen);
119 #endif
120 }
121 
122 int rlUdpSocket::bind(int port)
123 {
124  if(port < 0 || port >= 256*256) return -1;
125 
126  memset(&address,0,sizeof(address));
127  address.sin_family = AF_INET;
128  address.sin_port = htons((short) port);
129  address.sin_addr.s_addr = htonl(INADDR_ANY);
130  // bind socket
131  if(::bind(s, (sockaddr *) &address, sizeof(address)) < 0)
132  {
133  ::printf("rlUdpSocket::setAdr() bind() failed port=%d\n", port);
134  return -1;
135  }
136  return 0;
137 }
138 
139 int rlUdpSocket::select(int timeout)
140 {
141  if(timeout < 0) return -1;
142  struct timeval timout;
143  fd_set wset,rset,eset;
144  int ret,maxfdp1;
145 
146  /* setup sockets to read */
147  maxfdp1 = s+1;
148  FD_ZERO(&rset);
149  FD_SET (s,&rset);
150  FD_ZERO(&wset);
151  FD_ZERO(&eset);
152  timout.tv_sec = timeout / 1000;
153  timout.tv_usec = (timeout % 1000) * 1000;
154 
155  ret = ::select(maxfdp1,&rset,&wset,&eset,&timout);
156  if(ret == 0) return 0; /* timeout */
157  return 1;
158 }
159 
160 int rlUdpSocket::recvfrom(void *buf, int maxlen, rlIpAdr *source, int timeout)
161 {
162  int ret, len;
163 
164  if(timeout >= 0)
165  {
166  ret = select(timeout);
167  if(ret != 1) return -1; // timeout
168  }
169  if(debug) ::printf("rlUdpSocket()::recvfrom() ...\n");
170  len = sizeof(source->address);
171 #ifdef RLWIN32
172  ret = ::recvfrom(s, (char *) buf, maxlen, readflag,
173  (struct sockaddr *) &source->address, (int FAR *) &len);
174 #endif
175 #ifdef RLUNIX
176  ret = ::recvfrom(s, buf, maxlen, readflag,
177  (struct sockaddr *) &source->address, (socklen_t *) &len);
178 #endif
179 #ifdef __VMS
180  ret = ::recvfrom(s, buf, maxlen, readflag,
181  (struct sockaddr *) &source->address, (size_t *) &len);
182 #endif
183  if(ret < 0)
184  {
185  ::printf("ERROR: rlUdpSocket::read()\n");
186  return -2;
187  }
188  if(debug)
189  {
190  unsigned char *cbuf = (unsigned char *) buf;
191  ::printf("rlUdpSocket()::recvfrom() ret=%d data=[0x%x",ret,cbuf[0]);
192  for(int i=1; i<ret; i++) ::printf(",0x%x",cbuf[i]);
193  ::printf("]\n");
194  }
195  return ret;
196 }
197 
198 int rlUdpSocket::sendto(const void *buf, int len, rlIpAdr *dest)
199 {
200 #ifdef RLWIN32
201  int ret = ::sendto(s, (const char *) buf, len, writeflag,
202  (struct sockaddr *) &dest->address, sizeof(struct sockaddr_in));
203 #else
204  int ret = ::sendto(s, buf, len, writeflag,
205  (struct sockaddr *) &dest->address, sizeof(struct sockaddr_in));
206 #endif
207  if(ret < 0) ::printf("ERROR: rlUdpSocket::sendto()\n");
208  if(debug)
209  {
210  unsigned char *cbuf = (unsigned char *) buf;
211  ::printf("rlUdpSocket()::sendto() ret=%d data=[0x%x",ret,cbuf[0]);
212  for(int i=1; i<ret; i++) ::printf(",0x%x",cbuf[i]);
213  ::printf("]\n");
214  }
215  return ret;
216 }
217 
218 int rlUdpSocket::printf(rlIpAdr *dest, const char *format, ...)
219 {
220  int ret;
221  char message[rl_PRINTF_LENGTH]; // should be big enough
222 
223  va_list ap;
224  va_start(ap,format);
225  ret = rlvsnprintf(message, rl_PRINTF_LENGTH - 1, format, ap);
226  va_end(ap);
227  if(ret < 0) return ret;
228  return sendto(message,strlen(message)+1,dest);
229 }
230 
231 //#define TESTING
232 #ifdef TESTING
233 
234 int main(int ac, char **av)
235 {
236  int ret;
237  char buf[1024];
238  rlUdpSocket udp;
239  rlIpAdr dest;
240  dest.setAdr("localhost",5050);
241 
242  if(ac == 2) // client
243  {
244  while(1)
245  {
246  sleep(1);
247  ret = udp.sendto(av[1], strlen(av[1])+1, &dest);
248  if(ret > 0)
249  {
250  printf("udp.sendto(%s) ret=%d\n",av[1],ret);
251  }
252  else printf("udp.sendto() failed\n");
253  }
254  }
255  else // server
256  {
257  rlIpAdr source;
258  ret = udp.bind(5050);
259  while(1)
260  {
261  if((ret = udp.recvfrom(buf,sizeof(buf), &source, 1000)) > 0)
262  {
263  printf("udp.recvfrom(%s) ret=%d\n",buf,ret);
264  if(dest == source) printf("dest==source\n");
265  else printf("dest!=source\n");
266  }
267  else printf("udp.recvfrom() failed or timeout\n");
268  }
269  }
270  return 0;
271 }
272 
273 #endif
virtual ~rlIpAdr()
Definition: rludpsocket.cpp:27
int recvfrom(void *buf, int maxlen, rlIpAdr *source, int timeout=-1)
int setSockopt(int opt)
Definition: rludpsocket.cpp:98
int printf(rlIpAdr *dest, const char *format,...)
#define rl_PRINTF_LENGTH
Definition: rldefine.h:71
int setAdr(const char *adr, int port)
Definition: rludpsocket.cpp:31
int select(int timeout)
int bind(int port)
int rlvsnprintf(char *text, int len, const char *format, va_list ap)
Definition: rlcutil.cpp:197
int operator==(rlIpAdr &address1)
Definition: rludpsocket.cpp:63
int main()
Definition: rlcorba.cpp:18
struct sockaddr_in address
Definition: rludpsocket.h:97
int sendto(const void *buf, int len, rlIpAdr *dest)
virtual ~rlUdpSocket()
Definition: rludpsocket.cpp:86
rlUdpSocket(int debug=0)
Definition: rludpsocket.cpp:72
struct sockaddr_in address
Definition: rludpsocket.h:47
int rlwsa()
Definition: rlsocket.cpp:68