WvStreams
wvudp.cc
1/*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * WvUDPStream can send and receive packets on a connectionless UDP socket.
6 * See wvudp.h for details.
7 */
8#include "wvudp.h"
9
10#ifndef WIN32
11#include <sys/socket.h>
12#else
13#define setsockopt(a,b,c,d,e) setsockopt(a,b,c, (const char*) d,e)
14#define recvfrom(a,b,c,d,e,f) recvfrom(a, (char *) b, c, d, e, f)
15#define sendto(a,b,c,d,e,f) sendto(a,(const char*) b,c,d,e,f)
16#undef errno
17#define errno GetLastError()
18#endif
19
20#include <fcntl.h>
21
22#ifdef ISDARWIN
23# define socklen_t int
24#endif
25
27 const WvIPPortAddr &_rem) :
28 localaddr(), remaddr(_rem)
29{
30 int x = 1;
31 setfd(socket(PF_INET, SOCK_DGRAM, 0));
32 if (getfd() < 0
33 || setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) < 0)
34 {
35 seterr(errno);
36 return;
37 }
38
40 set_nonblock(true);
41
42 struct sockaddr *sa = _local.sockaddr();
43 if (bind(getfd(), sa, _local.sockaddr_len()))
44 {
45 delete sa;
46 seterr(errno);
47 return;
48 }
49 delete sa;
50
51 struct sockaddr_in nsa;
52 socklen_t nsalen = sizeof(nsa);
53 if (getsockname(getfd(), (sockaddr *)&nsa, &nsalen) < 0)
54 {
55 seterr(errno);
56 return;
57 }
58 localaddr = WvIPPortAddr(&nsa);
59
60 if (WvIPAddr(_rem) != WvIPAddr())
61 {
62 struct sockaddr *sa = _rem.sockaddr();
63 if (connect(getfd(), sa, _rem.sockaddr_len()))
64 {
65 delete sa;
66 seterr(errno);
67 return;
68 }
69 delete sa;
70 }
71}
72
73
74WvUDPStream::~WvUDPStream()
75{
76}
77
78
80{
81 return &remaddr;
82}
83
84
85const WvAddr *WvUDPStream::local() const
86{
87 return &localaddr;
88}
89
90
91size_t WvUDPStream::uread(void *buf, size_t count)
92{
93 if (!isok() || !buf || !count) return 0;
94
95 struct sockaddr_in from;
96 socklen_t fromlen = sizeof(from);
97 int in = recvfrom(getfd(), buf, count, 0, (sockaddr *)&from, &fromlen);
98
99 if (in >= 0)
100 remaddr = WvIPPortAddr(&from);
101
102 // errors in UDP are ignored
103 return in < 0 ? 0 : in;
104}
105
106
107size_t WvUDPStream::uwrite(const void *buf, size_t count)
108{
109 if (!isok() || !buf || !count) return 0;
110
111 // pretend everything worked if there is nowhere to send data
112 if (remaddr.is_zero()) return count;
113
114 struct sockaddr *to = remaddr.sockaddr();
115 size_t tolen = remaddr.sockaddr_len();
116 int out;
117
118 out = sendto(getfd(), buf, count, 0, to, tolen);
119
120 if (out < 0 && errno == EACCES) // permission denied
121 seterr(EACCES);
122
123 delete to;
124
125 // errors in UDP are ignored
126 // pretend that the write always succeeds even if the kernel
127 // complains since we don't want datagrams backing up in the
128 // buffer and forming merged datagrams as a result
129 return out < 0 ? 0 : out;
130}
131
132
133void WvUDPStream::enable_broadcasts()
134{
135 int value = 1;
136
137 if (!isok()) return;
138
139 setsockopt(getfd(), SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
140}
Base class for different address types, each of which will have the ability to convert itself to/from...
void setfd(int fd)
Sets the file descriptor for both reading and writing.
int getfd() const
Returns the Unix file descriptor for reading and writing.
virtual bool isok() const
return true if the stream is actually usable right now
void set_nonblock(bool nonblock)
Make the fds on this stream blocking or non-blocking.
Definition wvfdstream.cc:97
void set_close_on_exec(bool close_on_exec)
Make the fds on this stream close-on-exec or not.
An IP address is made up of a "dotted quad" – four decimal numbers in the form www....
An IP+Port address also includes a port number, with the resulting form www.xxx.yyy....
virtual void seterr(int _errnum)
Override seterr() from WvError so that it auto-closes the stream.
Definition wvstream.cc:451
WvUDPStream(const WvIPPortAddr &_local, const WvIPPortAddr &_rem)
connect a new socket
Definition wvudp.cc:26
virtual size_t uread(void *buf, size_t count)
unbuffered I/O functions; these ignore the buffer, which is handled by read().
Definition wvudp.cc:91
virtual const WvAddr * src() const
return the remote address (source of incoming packets, target of outgoing packets).
Definition wvudp.cc:79
virtual size_t uwrite(const void *buf, size_t count)
unbuffered I/O functions; these ignore the buffer, which is handled by write().
Definition wvudp.cc:107