Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvudp.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * WvUDPStream can send and receive packets on a connectionless UDP socket.
00006  * See wvudp.h for details.
00007  */
00008 #include "wvudp.h"
00009 
00010 #ifndef WIN32
00011 #include <sys/socket.h>
00012 #else
00013 #define setsockopt(a,b,c,d,e) setsockopt(a,b,c, (const char*) d,e)
00014 #define recvfrom(a,b,c,d,e,f) recvfrom(a, (char *) b, c, d, e, f)
00015 #define sendto(a,b,c,d,e,f) sendto(a,(const char*) b,c,d,e,f)
00016 #undef errno
00017 #define errno GetLastError()
00018 #endif
00019 
00020 #include <fcntl.h>
00021 
00022 #ifdef ISDARWIN
00023 # define socklen_t int
00024 #endif
00025 
00026 WvUDPStream::WvUDPStream(const WvIPPortAddr &_local,
00027     const WvIPPortAddr &_rem) :
00028     localaddr(), remaddr(_rem)
00029 {
00030     int x = 1;
00031     setfd(socket(PF_INET, SOCK_DGRAM, 0));
00032     if (getfd() < 0 
00033 #ifndef _WIN32
00034         || fcntl(getfd(), F_SETFD, 1)
00035         || fcntl(getfd(), F_SETFL, O_RDWR | O_NONBLOCK)
00036 #else
00037         || ioctlsocket(getfd(), FIONBIO, (u_long*) &x) // non-blocking
00038 #endif        
00039         || setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) < 0
00040         )
00041     {
00042         seterr(errno);
00043         return;
00044     }
00045 
00046     struct sockaddr *sa = _local.sockaddr();
00047     if (bind(getfd(), sa, _local.sockaddr_len()))
00048     {
00049         delete sa;
00050         seterr(errno);
00051         return;
00052     }
00053     delete sa;
00054     
00055     struct sockaddr_in nsa;
00056     socklen_t nsalen = sizeof(nsa);
00057     if (getsockname(getfd(), (sockaddr *)&nsa, &nsalen) < 0)
00058     {
00059         seterr(errno);
00060         return;
00061     }
00062     localaddr = WvIPPortAddr(&nsa);
00063     
00064     if (WvIPAddr(_rem) != WvIPAddr())
00065     {
00066         struct sockaddr *sa = _rem.sockaddr();
00067         if (connect(getfd(), sa, _rem.sockaddr_len()))
00068         {
00069             delete sa;
00070             seterr(errno);
00071             return;
00072         }
00073         delete sa;
00074     }
00075 }
00076 
00077 
00078 WvUDPStream::~WvUDPStream()
00079 {
00080 }
00081 
00082 
00083 const WvAddr *WvUDPStream::src() const
00084 {
00085     return &remaddr;
00086 }
00087 
00088 
00089 const WvAddr *WvUDPStream::local() const
00090 {
00091     return &localaddr;
00092 }
00093 
00094 
00095 size_t WvUDPStream::uread(void *buf, size_t count)
00096 {
00097     if (!isok() || !buf || !count) return 0;
00098     
00099     struct sockaddr_in from;
00100     socklen_t fromlen = sizeof(from);
00101     int in = recvfrom(getfd(), buf, count, 0, (sockaddr *)&from, &fromlen);
00102     
00103     if (in >= 0)
00104         remaddr = WvIPPortAddr(&from);
00105 
00106     // errors in UDP are ignored
00107     return in < 0 ? 0 : in;
00108 }
00109 
00110 
00111 size_t WvUDPStream::uwrite(const void *buf, size_t count)
00112 {
00113     if (!isok() || !buf || !count) return 0;
00114     
00115     struct sockaddr *to = remaddr.sockaddr();
00116     size_t tolen = remaddr.sockaddr_len();
00117     int out;
00118     
00119     out = sendto(getfd(), buf, count, 0, to, tolen);
00120     
00121     if (out < 0 && errno == EACCES) // permission denied
00122         seterr(EACCES);
00123     
00124     free(to);
00125     
00126     // errors in UDP are ignored
00127     // pretend that the write always succeeds even if the kernel
00128     // complains since we don't want datagrams backing up in the
00129     // buffer and forming merged datagrams as a result
00130     return out < 0 ? 0 : out;
00131 }
00132 
00133 
00134 void WvUDPStream::enable_broadcasts()
00135 {
00136     int value = 1;
00137     
00138     if (!isok()) return;
00139     
00140     setsockopt(getfd(), SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
00141 }

Generated on Sat Feb 21 21:05:34 2004 for WvStreams by doxygen 1.3.5