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 Tue Oct 5 01:09:21 2004 for WvStreams by doxygen 1.3.7