aboutsummaryrefslogtreecommitdiff
path: root/docs/doxygen/nel/sock_8cpp-source.html
diff options
context:
space:
mode:
authorneodarz <neodarz@neodarz.net>2018-08-11 20:21:34 +0200
committerneodarz <neodarz@neodarz.net>2018-08-11 20:21:34 +0200
commit0ea5fc66924303d1bf73ba283a383e2aadee02f2 (patch)
tree2568e71a7ccc44ec23b8bb3f0ff97fb6bf2ed709 /docs/doxygen/nel/sock_8cpp-source.html
downloadnevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.tar.xz
nevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.zip
Initial commit
Diffstat (limited to '')
-rw-r--r--docs/doxygen/nel/sock_8cpp-source.html663
1 files changed, 663 insertions, 0 deletions
diff --git a/docs/doxygen/nel/sock_8cpp-source.html b/docs/doxygen/nel/sock_8cpp-source.html
new file mode 100644
index 00000000..b6394c1d
--- /dev/null
+++ b/docs/doxygen/nel/sock_8cpp-source.html
@@ -0,0 +1,663 @@
+<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+ <TITLE>nevrax.org : docs</TITLE>
+ <LINK REL=stylesheet TYPE="text/css" HREF="http://www.nevrax.org/inc/css/nevrax.css">
+ <link href="doxygen.css" rel="stylesheet" type="text/css">
+</HEAD>
+<BODY MARGINHEIGHT="0" MARGINWIDTH="0">
+
+<!-- uplinks -->
+<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0>
+ <TR>
+ <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD>
+ <TD WIDTH=140 BGCOLOR=#dddddd><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="16" BORDER=0 ALT=""></TD>
+ <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD>
+ <TD><IMG width=6 height=14 SRC="http://www.nevrax.org/inc/img/reddots.gif" ALT="#" VSPACE=2 HSPACE=2 BORDER=0 ></TD><TD VALIGN=middle>&nbsp;<A CLASS=uplinks HREF=http://www.nevrax.org><b>Home</B></FONT></A>&nbsp;&nbsp;&nbsp;</TD>
+ <TD><IMG width=6 height=14 SRC="http://www.nevrax.org/inc/img/reddots.gif" ALT="#" VSPACE=2 HSPACE=2 BORDER=0 ></TD><TD VALIGN=middle>&nbsp;<A CLASS=uplinks HREF=http://www.nevrax.com><b>nevrax.com</B></FONT></A>&nbsp;&nbsp;&nbsp;</TD>
+ </TR>
+</TABLE>
+
+<!-- banner Nevrax -->
+<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%>
+ <TR><TD BGCOLOR="#000000" BACKGROUND="http://www.nevrax.org/inc/img/black_banner.jpg"><A HREF="http://www.nevrax.org"><IMG SRC="http://www.nevrax.org/inc/img/nevrax.gif" WIDTH="170" HEIGHT="45" BORDER=0 ALT="Nevrax" ></A></TD></TR>
+</TABLE>
+
+<!-- main table -->
+<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 height=100%>
+ <TR>
+ <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="10" BORDER=0 ALT=""></TD>
+ <TD WIDTH=140 BGCOLOR=#dddddd VALIGN=TOP ALIGN=middle><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="10" BORDER=0 ALT="">
+
+ <!------ Begin Box ------>
+ <TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 BGCOLOR=black><TR><TD><TABLE border=0 cellspacing=2 cellpadding=0 width=120><tr><TD ALIGN=middle bgcolor=black>
+ <FONT COLOR=white FACE="sans-serif"><B>Nevrax.org</B></FONT></TD></TR><tr><td colspan=2 bgcolor=#FFFFFF>
+ <TABLE cellspacing=0 cellpadding=1 border=0>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/news/" TITLE="Rubrique news"><img width=13 height=15 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-news.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/news/" TITLE="News">News</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/mail/" TITLE="Rubrique mail"><img width=15 height=11 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-mail.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/mail/" TITLE="Mailing list archive">Mailing-list</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/docs/" TITLE="Rubrique docs"><img width=14 height=16 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-docs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/docs/" TITLE="Documentation">Documentation</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/cvs/" TITLE="Rubrique cvs"><img width=13 height=17 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-cvs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/cvs/" TITLE="CVS Web">CVS</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/bugs/" TITLE="Rubrique bugs"><img width=20 height=16 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-bugs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/bugs/" TITLE="Bugtracking">Bugs</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/GPL.php3" TITLE="Rubrique license"><img width=18 height=12 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-gpl.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/GPL.php3" TITLE="License">License</a></td></tr>
+ </TABLE>
+ </TD></TR></TABLE></TD></TR></TABLE>
+ <!------ End Box ------>
+
+ </TD>
+ <TD WIDTH=15><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD>
+ <TD ALIGN=left valign=top><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="10" BORDER=0 ALT="">
+
+<!-- title -->
+<TABLE background="http://www.nevrax.org/inc/img/redline.gif" CELLSPACING=0 CELLPADDING=0 BORDER=0 width=100%><tr><td>
+<A HREF="http://www.nevrax.org/docs/"><img src="http://www.nevrax.org/inc/img/t_docs.gif" ALT="Docs" HEIGHT=20 BORDER=0></A>
+</td><td><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="1" HEIGHT="1" BORDER=0 ALT="">
+</td></tr></table>
+&nbsp;
+
+<!-- block -->
+<TABLE bgcolor="#dddddd" CELLSPACING=0 CELLPADDING=0 BORDER=0 width=100%><tr><td width=1% valign=middle><img width=6 height=14 hspace=2 vspace=2 src="http://www.nevrax.org/inc/img/reddots.gif"></TD>
+ <TD><B>Documentation</B></TD>
+ <TD ALIGN=RIGHT>&nbsp;</td>
+</tr></table>
+<!-- Generated by Doxygen 1.2.14 -->
+<center>
+<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="namespaces.html">Namespace List</a> &nbsp; <a class="qindex" href="hierarchy.html">Class Hierarchy</a> &nbsp; <a class="qindex" href="classes.html">Alphabetical List</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="namespacemembers.html">Namespace Members</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; <a class="qindex" href="globals.html">File Members</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; <a class="qindexRef" doxygen="_cgi:http://www.nevrax.org/cgi-bin/nel-search.cgi" href="http://www.nevrax.org/cgi-bin/nel-search.cgi">Search</a> &nbsp; </center>
+<hr><h1>sock.cpp</h1><a href="sock_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001
+00007 <font class="comment">/* Copyright, 2000 Nevrax Ltd.</font>
+00008 <font class="comment"> *</font>
+00009 <font class="comment"> * This file is part of NEVRAX NEL.</font>
+00010 <font class="comment"> * NEVRAX NEL is free software; you can redistribute it and/or modify</font>
+00011 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
+00012 <font class="comment"> * the Free Software Foundation; either version 2, or (at your option)</font>
+00013 <font class="comment"> * any later version.</font>
+00014 <font class="comment"></font>
+00015 <font class="comment"> * NEVRAX NEL is distributed in the hope that it will be useful, but</font>
+00016 <font class="comment"> * WITHOUT ANY WARRANTY; without even the implied warranty of</font>
+00017 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</font>
+00018 <font class="comment"> * General Public License for more details.</font>
+00019 <font class="comment"></font>
+00020 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
+00021 <font class="comment"> * along with NEVRAX NEL; see the file COPYING. If not, write to the</font>
+00022 <font class="comment"> * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,</font>
+00023 <font class="comment"> * MA 02111-1307, USA.</font>
+00024 <font class="comment"> */</font>
+00025
+00026 <font class="preprocessor">#include "<a class="code" href="stdnet_8h.html">stdnet.h</a>"</font>
+00027
+00028 <font class="preprocessor">#include "<a class="code" href="sock_8h.html">nel/net/sock.h</a>"</font>
+00029 <font class="preprocessor">#include "<a class="code" href="time__nl_8h.html">nel/misc/time_nl.h</a>"</font>
+00030
+00031 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font>
+00032 <font class="preprocessor"></font>
+00033 <font class="preprocessor"># include &lt;winsock2.h&gt;</font>
+00034 <font class="comment">//# include &lt;windows.h&gt;</font>
+00035 <font class="preprocessor"># define socklen_t int</font>
+00036 <font class="preprocessor"></font><font class="preprocessor"># define ERROR_NUM WSAGetLastError()</font>
+00037 <font class="preprocessor"></font><font class="preprocessor"># define ERROR_WOULDBLOCK WSAEWOULDBLOCK</font>
+00038 <font class="preprocessor"></font>
+00039 <font class="preprocessor">#elif defined NL_OS_UNIX</font>
+00040 <font class="preprocessor"></font>
+00041 <font class="preprocessor"># include &lt;<a class="code" href="unistd_8h.html">unistd.h</a>&gt;</font>
+00042 <font class="preprocessor"># include &lt;sys/types.h&gt;</font>
+00043 <font class="preprocessor"># include &lt;sys/time.h&gt;</font>
+00044 <font class="preprocessor"># include &lt;sys/socket.h&gt;</font>
+00045 <font class="preprocessor"># include &lt;netinet/in.h&gt;</font>
+00046 <font class="preprocessor"># include &lt;netinet/tcp.h&gt;</font>
+00047 <font class="preprocessor"># include &lt;arpa/inet.h&gt;</font>
+00048 <font class="preprocessor"># include &lt;netdb.h&gt;</font>
+00049 <font class="preprocessor"># include &lt;fcntl.h&gt;</font>
+00050 <font class="preprocessor"># include &lt;errno.h&gt;</font>
+00051 <font class="preprocessor"># define SOCKET_ERROR -1</font>
+00052 <font class="preprocessor"></font><font class="preprocessor"># define INVALID_SOCKET -1</font>
+00053 <font class="preprocessor"></font><font class="preprocessor"># define ERROR_NUM errno</font>
+00054 <font class="preprocessor"></font><font class="preprocessor"># define ERROR_WOULDBLOCK EWOULDBLOCK</font>
+00055 <font class="preprocessor"></font><font class="preprocessor"># define ERROR_MSG strerror(errno)</font>
+00056 <font class="preprocessor"></font><font class="keyword">typedef</font> <font class="keywordtype">int</font> SOCKET;
+00057
+00058 <font class="preprocessor">#endif</font>
+00059 <font class="preprocessor"></font>
+00060 <font class="keyword">using</font> <font class="keyword">namespace </font>std;
+00061 <font class="keyword">using</font> <font class="keyword">namespace </font>NLMISC;
+00062
+00063 <font class="keyword">namespace </font>NLNET {
+00064
+00065
+00066 <font class="keywordtype">bool</font> CSock::_Initialized = <font class="keyword">false</font>;
+00067
+00068 <font class="keywordtype">long</font> CSock::_TimeoutS = 0;
+00069
+00070 <font class="keywordtype">long</font> CSock::_TimeoutMs = 0;
+00071
+00072
+00073 <font class="comment">/*</font>
+00074 <font class="comment"> * ESocket constructor</font>
+00075 <font class="comment"> */</font>
+00076 ESocket::ESocket( <font class="keyword">const</font> <font class="keywordtype">char</font> *reason, <font class="keywordtype">bool</font> systemerror, CInetAddress *addr )
+00077 {
+00078 <font class="comment">/*it doesnt work on linux, should do something more cool</font>
+00079 <font class="comment"> std::stringstream ss;</font>
+00080 <font class="comment"> ss &lt;&lt; "Socket error: " &lt;&lt; reason;</font>
+00081 <font class="comment"> if ( systemerror )</font>
+00082 <font class="comment"> {</font>
+00083 <font class="comment"> ss &lt;&lt; " (" &lt;&lt; ERROR_NUM;</font>
+00084 <font class="comment">#ifdef NL_OS_UNIX</font>
+00085 <font class="comment"> ss &lt;&lt; ": " &lt;&lt; ERROR_MSG;</font>
+00086 <font class="comment">#endif</font>
+00087 <font class="comment"> ss &lt;&lt; ") " &lt;&lt; std::endl;</font>
+00088 <font class="comment"> }</font>
+00089 <font class="comment"> _Reason = ss.str();</font>
+00090 <font class="comment"> */</font>
+00091 _Reason = <font class="stringliteral">"Socket error: "</font>;
+00092 <a class="code" href="types__nl_8h.html#a13">uint</a> errornum = CSock::getLastError();
+00093 <font class="keywordtype">char</font> str[256];
+00094 <font class="keywordflow">if</font> ( addr != NULL )
+00095 {
+00096 <font class="comment">// Version with address</font>
+00097 <a class="code" href="namespaceNLMISC.html#a186">smprintf</a>( str, 256, reason, addr-&gt;asString().c_str() ); <font class="comment">// reason *must* contain "%s"</font>
+00098 _Reason += str;
+00099 }
+00100 <font class="keywordflow">else</font>
+00101 {
+00102 <font class="comment">// Version without address</font>
+00103 _Reason += reason;
+00104 }
+00105 <font class="keywordflow">if</font> ( systemerror )
+00106 {
+00107 _Reason += <font class="stringliteral">" ("</font>;
+00108 <a class="code" href="namespaceNLMISC.html#a186">smprintf</a>( str, 256, <font class="stringliteral">"%d"</font>, errornum );
+00109 _Reason += str;
+00110 <font class="keywordflow">if</font> ( errornum != 0 )
+00111 {
+00112 _Reason += <font class="stringliteral">": "</font>;
+00113 _Reason += CSock::errorString( errornum );
+00114 }
+00115 _Reason += <font class="stringliteral">")"</font>;
+00116 }
+00117 <a class="code" href="debug_8h.html#a2">nlwarning</a>( <font class="stringliteral">"Exception will be launched: %s"</font>, _Reason.c_str() );
+00118 }
+00119
+00120
+00121 <font class="comment">/*</font>
+00122 <font class="comment"> * Initializes the network engine if it is not already done (under Windows, calls WSAStartup()).</font>
+00123 <font class="comment"> */</font>
+00124 <font class="keywordtype">void</font> CSock::initNetwork()
+00125 {
+00126 <font class="keywordflow">if</font> ( ! CSock::_Initialized )
+00127 {
+00128 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font>
+00129 <font class="preprocessor"></font> WORD winsock_version = MAKEWORD( 2, 0 );
+00130 WSADATA wsaData;
+00131 <font class="keywordflow">if</font> ( WSAStartup( winsock_version, &amp;wsaData ) != 0 )
+00132 {
+00133 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Winsock initialization failed"</font> );
+00134 }
+00135 <font class="preprocessor">#endif</font>
+00136 <font class="preprocessor"></font> CSock::_Initialized = <font class="keyword">true</font>;
+00137 }
+00138 }
+00139
+00140 <font class="comment">/*</font>
+00141 <font class="comment"> * Releases the network engine</font>
+00142 <font class="comment"> */</font>
+00143 <font class="keywordtype">void</font> CSock::releaseNetwork()
+00144 {
+00145 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font>
+00146 <font class="preprocessor"></font> WSACleanup();
+00147 <font class="preprocessor">#endif</font>
+00148 <font class="preprocessor"></font> CSock::_Initialized = <font class="keyword">false</font>;
+00149 }
+00150
+00151
+00152 <font class="comment">/* Returns the code of the last error that has occured.</font>
+00153 <font class="comment"> * Note: This code is platform-dependant. On Unix, it is errno; on Windows it is the Winsock error code.</font>
+00154 <font class="comment"> * See also errorString()</font>
+00155 <font class="comment"> */</font>
+00156 <a class="code" href="types__nl_8h.html#a13">uint</a> CSock::getLastError()
+00157 {
+00158 <font class="keywordflow">return</font> (uint)ERROR_NUM;
+00159 }
+00160
+00161
+00162 <font class="comment">/*</font>
+00163 <font class="comment"> * Returns a string explaining the network error (see getLastError())</font>
+00164 <font class="comment"> */</font>
+00165 std::string CSock::errorString( <a class="code" href="types__nl_8h.html#a13">uint</a> errorcode )
+00166 {
+00167 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font>
+00168 <font class="preprocessor"></font> <font class="keywordflow">switch</font>( errorcode )
+00169 {
+00170 <font class="keywordflow">case</font> WSAEINTR <font class="comment">/*10004*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Blocking operation interrupted"</font>;
+00171 <font class="keywordflow">case</font> WSAEINVAL <font class="comment">/*10022*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Invalid socket (maybe not bound) or argument"</font>;
+00172 <font class="keywordflow">case</font> WSAEMFILE <font class="comment">/*10024*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Too many open sockets"</font>;
+00173 <font class="keywordflow">case</font> WSAENOTSOCK <font class="comment">/*10038*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Socket operation on nonsocket (maybe invalid select descriptor)"</font>;
+00174 <font class="keywordflow">case</font> WSAEMSGSIZE <font class="comment">/*10040*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Message too long"</font>;
+00175 <font class="keywordflow">case</font> WSAEADDRINUSE <font class="comment">/*10048*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Address already in use (is this service already running in this computer?)"</font>;
+00176 <font class="keywordflow">case</font> WSAEADDRNOTAVAIL<font class="comment">/*10049*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Address not available"</font>;
+00177 <font class="keywordflow">case</font> WSAENETDOWN <font class="comment">/*10050*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Network is down"</font>;
+00178 <font class="keywordflow">case</font> WSAENETUNREACH <font class="comment">/*10051*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Network is unreachable"</font>;
+00179 <font class="keywordflow">case</font> WSAECONNRESET <font class="comment">/*10054*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Connection reset by peer"</font>;
+00180 <font class="keywordflow">case</font> WSAENOBUFS <font class="comment">/*10055*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"No buffer space available; please close applications or reboot"</font>;
+00181 <font class="keywordflow">case</font> WSAESHUTDOWN <font class="comment">/*10058*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Cannot send/receive after socket shutdown"</font>;
+00182 <font class="keywordflow">case</font> WSAETIMEDOUT <font class="comment">/*10060*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Connection timed-out"</font>;
+00183 <font class="keywordflow">case</font> WSAECONNREFUSED <font class="comment">/*10061*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Connection refused, the server may be offline"</font>;
+00184 <font class="keywordflow">case</font> WSAEHOSTUNREACH <font class="comment">/*10065*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"Remote host is unreachable"</font>;
+00185 <font class="keywordflow">case</font> WSANOTINITIALISED <font class="comment">/*093*/</font>: <font class="keywordflow">return</font> <font class="stringliteral">"'Windows Sockets' not initialized"</font>;
+00186 <font class="keywordflow">default</font>: <font class="keywordflow">return</font> <font class="stringliteral">""</font>;
+00187 }
+00188 <font class="preprocessor">#elif defined NL_OS_UNIX</font>
+00189 <font class="preprocessor"></font> <font class="keywordflow">return</font> std::string( strerror( errorcode ) );
+00190 <font class="preprocessor">#endif</font>
+00191 <font class="preprocessor"></font>
+00192 }
+00193
+00194
+00195
+00196 <font class="comment">/*</font>
+00197 <font class="comment"> * Constructor</font>
+00198 <font class="comment"> */</font>
+00199 CSock::CSock( <font class="keywordtype">bool</font> logging ) :
+00200 _Sock( INVALID_SOCKET ),
+00201 _Logging( logging ),
+00202 _BytesReceived( 0 ),
+00203 _BytesSent( 0 ),
+00204 _NonBlocking( false ),
+00205 _MaxReceiveTime( 0 ),
+00206 _MaxSendTime( 0 )
+00207 {
+00208 <a class="code" href="debug_8h.html#a6">nlassert</a>( CSock::_Initialized );
+00209 <font class="comment">/*{</font>
+00210 <font class="comment"> CSynchronized&lt;bool&gt;::CAccessor sync( &amp;_SyncConnected );</font>
+00211 <font class="comment"> sync.value() = false;</font>
+00212 <font class="comment"> }*/</font>
+00213 _Connected = <font class="keyword">false</font>;
+00214 }
+00215
+00216
+00217 <font class="comment">/*</font>
+00218 <font class="comment"> * Construct a CSock object using an existing connected socket descriptor and its associated remote address</font>
+00219 <font class="comment"> */</font>
+00220 CSock::CSock( SOCKET sock, <font class="keyword">const</font> CInetAddress&amp; remoteaddr ) :
+00221 _Sock( sock ),
+00222 _Logging( true ),
+00223 _BytesReceived( 0 ),
+00224 _BytesSent( 0 ),
+00225 _RemoteAddr( remoteaddr ),
+00226 _NonBlocking( false ),
+00227 _MaxReceiveTime( 0 ),
+00228 _MaxSendTime( 0 )
+00229 {
+00230 <a class="code" href="debug_8h.html#a6">nlassert</a>( CSock::_Initialized );
+00231 <font class="comment">/*{</font>
+00232 <font class="comment"> CSynchronized&lt;bool&gt;::CAccessor sync( &amp;_SyncConnected );</font>
+00233 <font class="comment"> sync.value() = true;</font>
+00234 <font class="comment"> }*/</font>
+00235 _Connected = <font class="keyword">true</font>;
+00236
+00237 <font class="comment">// Check remote address</font>
+00238 <font class="keywordflow">if</font> ( ! _RemoteAddr.isValid() )
+00239 {
+00240 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Could not init a socket object with an invalid address"</font>, <font class="keyword">false</font> );
+00241 }
+00242
+00243 <font class="comment">// Get local socket name</font>
+00244 setLocalAddress();
+00245 }
+00246
+00247
+00248 <font class="comment">/*</font>
+00249 <font class="comment"> * Creates the socket and get a valid descriptor</font>
+00250 <font class="comment"> */</font>
+00251 <font class="keywordtype">void</font> CSock::createSocket( <font class="keywordtype">int</font> <a class="code" href="driver__opengl__extension__def_8h.html#a240">type</a>, <font class="keywordtype">int</font> protocol )
+00252 {
+00253 <a class="code" href="debug_8h.html#a6">nlassert</a>( _Sock == INVALID_SOCKET );
+00254
+00255 _Sock = socket( AF_INET, <a class="code" href="driver__opengl__extension__def_8h.html#a240">type</a>, protocol ); <font class="comment">// or IPPROTO_IP (=0) ?</font>
+00256 <font class="keywordflow">if</font> ( _Sock == INVALID_SOCKET )
+00257 {
+00258 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Socket creation failed"</font> );
+00259 }
+00260
+00261 <font class="keywordflow">if</font> ( _Logging )
+00262 {
+00263 <font class="comment">// nldebug( "LNETL0: Socket %d open (TCP)", _Sock );</font>
+00264 }
+00265 }
+00266
+00267
+00268 <font class="comment">/*</font>
+00269 <font class="comment"> * Closes the listening socket</font>
+00270 <font class="comment"> */</font>
+00271 <font class="keywordtype">void</font> CSock::close()
+00272 {
+00273 <font class="keywordflow">if</font> ( _Logging )
+00274 {
+00275 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL0: Socket %d closing for %s at %s"</font>, _Sock, _RemoteAddr.asString().c_str(), _LocalAddr.asString().c_str() );
+00276 }
+00277 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font>
+00278 <font class="preprocessor"></font> closesocket( _Sock );
+00279 <font class="preprocessor">#elif defined NL_OS_UNIX</font>
+00280 <font class="preprocessor"></font> ::close( _Sock );
+00281 <font class="preprocessor">#endif</font>
+00282 <font class="preprocessor"></font> _Sock = INVALID_SOCKET;
+00283 }
+00284
+00285
+00286 <font class="comment">/*</font>
+00287 <font class="comment"> * Destructor</font>
+00288 <font class="comment"> */</font>
+00289 CSock::~CSock()
+00290 {
+00291 <a class="code" href="debug_8h.html#a1">nlinfo</a>( <font class="stringliteral">"Report for %s socket %s: Max send time: %u Max recv time: %u"</font>, _NonBlocking?<font class="stringliteral">"non-blocking"</font>:<font class="stringliteral">"blocking"</font>, remoteAddr().asString().c_str(), _MaxSendTime, _MaxReceiveTime );
+00292 <a class="code" href="debug_8h.html#a1">nlinfo</a>( <font class="stringliteral">"Max send time: %u"</font>, _MaxSendTime);
+00293 <font class="keywordflow">if</font> ( _Sock != INVALID_SOCKET )
+00294 {
+00295 <font class="keywordflow">if</font> ( _Logging )
+00296 {
+00297 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL0: Socket %d closing for %s at %s"</font>, _Sock, _RemoteAddr.asString().c_str(), _LocalAddr.asString().c_str() );
+00298 }
+00299
+00300 <font class="keywordflow">if</font> ( connected() )
+00301 {
+00302 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font>
+00303 <font class="preprocessor"></font> shutdown( _Sock, SD_BOTH );
+00304 }
+00305 closesocket( _Sock );
+00306 <font class="preprocessor">#elif defined NL_OS_UNIX</font>
+00307 <font class="preprocessor"></font> shutdown( _Sock, SHUT_RDWR );
+00308 }
+00309 ::close( _Sock );
+00310 <font class="preprocessor">#endif</font>
+00311 <font class="preprocessor"></font> _Sock = INVALID_SOCKET;
+00312 }
+00313 }
+00314
+00315
+00316 <font class="comment">/*</font>
+00317 <font class="comment"> * Connection</font>
+00318 <font class="comment"> */</font>
+00319 <font class="keywordtype">void</font> CSock::connect( <font class="keyword">const</font> CInetAddress&amp; addr )
+00320 {
+00321 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL0: Socket %d connecting to %s..."</font>, _Sock, addr.asString().c_str() );
+00322
+00323 <font class="comment">// Check address</font>
+00324 <font class="keywordflow">if</font> ( ! addr.isValid() )
+00325 {
+00326 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Unable to connect to invalid address"</font>, <font class="keyword">false</font> );
+00327 }
+00328
+00329 <font class="preprocessor">#ifndef NL_OS_WINDOWS</font>
+00330 <font class="preprocessor"></font> <font class="comment">// Set Reuse Address On (does not work on Win98 and is useless on Win2000)</font>
+00331 <font class="keywordtype">int</font> value = <font class="keyword">true</font>;
+00332 <font class="keywordflow">if</font> ( setsockopt( _Sock, SOL_SOCKET, SO_REUSEADDR, &amp;value, <font class="keyword">sizeof</font>(value) ) == SOCKET_ERROR )
+00333 {
+00334 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"ReuseAddr failed"</font> );
+00335 }
+00336 <font class="preprocessor">#endif</font>
+00337 <font class="preprocessor"></font>
+00338 <font class="comment">// Connection (when _Sock is a datagram socket, connect establishes a default destination address)</font>
+00339 <font class="keywordflow">if</font> ( ::connect( _Sock, (<font class="keyword">const</font> sockaddr *)(addr.sockAddr()), <font class="keyword">sizeof</font>(sockaddr_in) ) != 0 )
+00340 {
+00341 <font class="comment">/* if ( _Logging )</font>
+00342 <font class="comment"> {</font>
+00343 <font class="comment">#ifdef NL_OS_WINDOWS</font>
+00344 <font class="comment"> nldebug( "Impossible to connect socket %d to %s %s (%d)", _Sock, addr.hostName().c_str(), addr.asIPString().c_str(), ERROR_NUM );</font>
+00345 <font class="comment">#elif defined NL_OS_UNIX</font>
+00346 <font class="comment"> nldebug( "Impossible to connect socket %d to %s %s (%d:%s)", _Sock, addr.hostName().c_str(), addr.asIPString().c_str(), ERROR_NUM, strerror(ERROR_NUM) );</font>
+00347 <font class="comment">#endif</font>
+00348 <font class="comment"> }</font>
+00349 <font class="comment">*/</font>
+00350 <font class="keywordflow">throw</font> ESocketConnectionFailed( addr );
+00351 }
+00352 setLocalAddress();
+00353 <font class="keywordflow">if</font> ( _Logging )
+00354 {
+00355 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL0: Socket %d connected to %s (local %s)"</font>, _Sock, addr.asString().c_str(), _LocalAddr.asString().c_str() );
+00356 }
+00357 _RemoteAddr = addr;
+00358
+00359 _BytesReceived = 0;
+00360 _BytesSent = 0;
+00361
+00362 <font class="comment">/*CSynchronized&lt;bool&gt;::CAccessor sync( &amp;_SyncConnected );</font>
+00363 <font class="comment"> sync.value() = true;*/</font>
+00364 _Connected = <font class="keyword">true</font>;
+00365 }
+00366
+00367
+00368 <font class="comment">/*</font>
+00369 <font class="comment"> * Checks if there is some data to receive</font>
+00370 <font class="comment"> */</font>
+00371 <font class="keywordtype">bool</font> CSock::dataAvailable()
+00372 {
+00373 fd_set fdset;
+00374 FD_ZERO( &amp;fdset );
+00375 FD_SET( _Sock, &amp;fdset );
+00376 timeval tv;
+00377 tv.tv_sec = CSock::_TimeoutS;
+00378 tv.tv_usec = CSock::_TimeoutMs;
+00379
+00380 <font class="comment">// Test for message received.</font>
+00381 <font class="keywordtype">int</font> res = select( _Sock+1, &amp;fdset, NULL, NULL, &amp;tv );
+00382 <font class="keywordflow">switch</font> ( res )
+00383 {
+00384 <font class="keywordflow">case</font> 0 : <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00385 <font class="keywordflow">case</font> -1 : <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"CSock::dataAvailable(): select failed"</font> ); <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00386 <font class="keywordflow">default</font> : <font class="keywordflow">return</font> <font class="keyword">true</font>;
+00387 }
+00388 }
+00389
+00390
+00391 <font class="comment">/*</font>
+00392 <font class="comment"> * Sets the local address</font>
+00393 <font class="comment"> */</font>
+00394 <font class="keywordtype">void</font> CSock::setLocalAddress()
+00395 {
+00396 sockaddr saddr;
+00397 socklen_t saddrlen = <font class="keyword">sizeof</font>(saddr);
+00398 <font class="keywordflow">if</font> ( getsockname( _Sock, &amp;saddr, &amp;saddrlen ) != 0 )
+00399 {
+00400 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Unable to find local address"</font> );
+00401 }
+00402 _LocalAddr.setSockAddr( (<font class="keyword">const</font> sockaddr_in *)&amp;saddr );
+00403 }
+00404
+00405
+00406 <font class="comment">/*</font>
+00407 <font class="comment"> * Sends data, or returns false if it would block</font>
+00408 <font class="comment"> */</font>
+00409 CSock::TSockResult CSock::send( <font class="keyword">const</font> <a class="code" href="types__nl_8h.html#a5">uint8</a> *buffer, <a class="code" href="types__nl_8h.html#a9">uint32</a>&amp; <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>, <font class="keywordtype">bool</font> throw_exception )
+00410 {
+00411 <a class="code" href="types__nl_8h.html#a9">uint32</a> realLen = <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>;
+00412 <a class="code" href="namespaceNLMISC.html#a176">TTicks</a> before = CTime::getPerformanceTime();
+00413 <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a> = ::send( _Sock, (<font class="keyword">const</font> <font class="keywordtype">char</font>*)buffer, <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>, 0 );
+00414 _MaxSendTime = max( (<a class="code" href="types__nl_8h.html#a9">uint32</a>)(CTime::ticksToSecond(CTime::getPerformanceTime()-before)*1000.0f), _MaxSendTime );
+00415
+00416 <font class="keywordflow">if</font> ( _Logging )
+00417 {
+00418 <font class="comment">// nldebug ("LNETL0: CSock::send(): Sent %d bytes to %d res: %d (%d)", realLen, _Sock, len, ERROR_NUM);</font>
+00419 }
+00420
+00421 <font class="keywordflow">if</font> ( <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a> == SOCKET_ERROR )
+00422 {
+00423 <font class="keywordflow">if</font> ( ERROR_NUM == ERROR_WOULDBLOCK )
+00424 {
+00425 <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a> = 0;
+00426 <font class="keywordflow">return</font> Ok;
+00427 }
+00428 <font class="keywordflow">if</font> ( throw_exception )
+00429 {
+00430 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Unable to send data"</font> );
+00431 }
+00432 <font class="keywordflow">return</font> <a class="code" href="namespaceNLNET.html#a113a18">Error</a>;
+00433 }
+00434 _BytesSent += <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>;
+00435
+00436 <font class="keywordflow">return</font> Ok;
+00437 }
+00438
+00439
+00440
+00441 <font class="comment">/*</font>
+00442 <font class="comment"> * Receives data</font>
+00443 <font class="comment"> */</font>
+00444 CSock::TSockResult CSock::receive( <a class="code" href="types__nl_8h.html#a5">uint8</a> *buffer, <a class="code" href="types__nl_8h.html#a9">uint32</a>&amp; <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>, <font class="keywordtype">bool</font> throw_exception )
+00445 {
+00446 <font class="keywordflow">if</font> ( _NonBlocking )
+00447 {
+00448 <font class="comment">// Receive incoming message (only the received part)</font>
+00449
+00450 <a class="code" href="types__nl_8h.html#a9">uint32</a> realLen = <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>;
+00451
+00452 <a class="code" href="namespaceNLMISC.html#a176">TTicks</a> before = CTime::getPerformanceTime();
+00453 <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a> = ::recv( _Sock, (<font class="keywordtype">char</font>*)buffer, <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>, 0 );
+00454
+00455 <font class="keywordflow">if</font> ( _Logging )
+00456 {
+00457 <font class="comment">// nldebug ("LNETL0: CSock::receive(): NBM Received %d bytes to %d res: %d (%d)", realLen, _Sock, len, ERROR_NUM);</font>
+00458 }
+00459
+00460 _MaxReceiveTime = max( (<a class="code" href="types__nl_8h.html#a9">uint32</a>)(CTime::ticksToSecond(CTime::getPerformanceTime()-before)*1000.0f), _MaxReceiveTime );
+00461 <font class="keywordflow">switch</font> ( len )
+00462 {
+00463 <font class="comment">// Graceful disconnection</font>
+00464 <font class="keywordflow">case</font> 0 :
+00465 {
+00466 <font class="comment">/*{</font>
+00467 <font class="comment"> CSynchronized&lt;bool&gt;::CAccessor sync( &amp;_SyncConnected );</font>
+00468 <font class="comment"> sync.value() = false;</font>
+00469 <font class="comment"> }*/</font>
+00470 _Connected = <font class="keyword">false</font>;
+00471 <font class="keywordflow">if</font> ( throw_exception )
+00472 {
+00473 <font class="keywordflow">throw</font> ESocketConnectionClosed();
+00474 }
+00475 <font class="keywordflow">return</font> CSock::ConnectionClosed;
+00476 }
+00477
+00478 <font class="comment">// Socket error or call would block</font>
+00479 <font class="keywordflow">case</font> SOCKET_ERROR :
+00480 {
+00481 <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a> = 0;
+00482 <font class="keywordflow">if</font> ( ERROR_NUM == ERROR_WOULDBLOCK )
+00483 {
+00484 <font class="comment">// Call would block</font>
+00485 <font class="keywordflow">return</font> CSock::WouldBlock;
+00486 }
+00487 <font class="keywordflow">else</font>
+00488 {
+00489 <font class="comment">// Socket error</font>
+00490 <font class="keywordflow">if</font> ( throw_exception )
+00491 {
+00492 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Unable to receive data"</font> );
+00493 }
+00494 <font class="keywordflow">return</font> CSock::Error;
+00495 }
+00496 }
+00497 }
+00498 }
+00499 <font class="keywordflow">else</font> <font class="comment">// Blocking Mode</font>
+00500 {
+00501 <font class="comment">// Receive incoming message, waiting until a complete message has arrived</font>
+00502 <a class="code" href="types__nl_8h.html#a13">uint</a> total = 0;
+00503 <a class="code" href="types__nl_8h.html#a13">uint</a> brecvd;
+00504
+00505 <a class="code" href="types__nl_8h.html#a9">uint32</a> realLen = <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>;
+00506
+00507 <font class="keywordflow">while</font> ( total &lt; <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a> )
+00508 {
+00509 <a class="code" href="namespaceNLMISC.html#a176">TTicks</a> before = CTime::getPerformanceTime();
+00510 brecvd = ::recv( _Sock, (<font class="keywordtype">char</font>*)(buffer+total), <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>-total, 0 );
+00511
+00512 <font class="comment">// nldebug ("LNETL0: CSock::receive(): BM Received %d bytes to %d res: %d (%d)", realLen, _Sock, len, ERROR_NUM);</font>
+00513
+00514 _MaxReceiveTime = max( (<a class="code" href="types__nl_8h.html#a9">uint32</a>)(CTime::ticksToSecond(CTime::getPerformanceTime()-before)*1000.0f), _MaxReceiveTime );
+00515
+00516 <font class="keywordflow">switch</font> ( brecvd )
+00517 {
+00518 <font class="comment">// Graceful disconnection</font>
+00519 <font class="keywordflow">case</font> 0 :
+00520 {
+00521 <font class="comment">/*{</font>
+00522 <font class="comment"> CSynchronized&lt;bool&gt;::CAccessor sync( &amp;_SyncConnected );</font>
+00523 <font class="comment"> sync.value() = false;</font>
+00524 <font class="comment"> }*/</font>
+00525 _Connected = <font class="keyword">false</font>;
+00526 <font class="keywordflow">if</font> ( throw_exception )
+00527 {
+00528 <font class="keywordflow">throw</font> ESocketConnectionClosed();
+00529 }
+00530 <font class="keywordflow">return</font> CSock::ConnectionClosed;
+00531 }
+00532
+00533 <font class="comment">// Socket error</font>
+00534 <font class="keywordflow">case</font> SOCKET_ERROR :
+00535 {
+00536 <font class="keywordflow">if</font> ( throw_exception )
+00537 {
+00538 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Unable to receive data"</font> );
+00539 }
+00540 <font class="keywordflow">return</font> CSock::Error;
+00541 }
+00542 }
+00543 total += brecvd;
+00544 }
+00545 }
+00546
+00547 <font class="comment">/*if ( _Logging )</font>
+00548 <font class="comment"> {</font>
+00549 <font class="comment"> nldebug( "LNETL0: Socket %d received %d bytes", _Sock, len );</font>
+00550 <font class="comment"> }*/</font>
+00551 _BytesReceived += <a class="code" href="driver__opengl__extension__def_8h.html#a230">len</a>;
+00552 <font class="keywordflow">return</font> CSock::Ok;
+00553 }
+00554
+00555
+00556 <font class="comment">/*</font>
+00557 <font class="comment"> * Returns if the socket is connected</font>
+00558 <font class="comment"> */</font>
+00559 <font class="keywordtype">bool</font> CSock::connected()
+00560 {
+00561 <font class="comment">/*bool b;</font>
+00562 <font class="comment"> {</font>
+00563 <font class="comment"> //nldebug( "LNETL0: CSock::connected-BEGIN (socket %u)", descriptor() );</font>
+00564 <font class="comment"> CSynchronized&lt;bool&gt;::CAccessor sync( &amp;_SyncConnected );</font>
+00565 <font class="comment"> b = sync.value();</font>
+00566 <font class="comment"> }</font>
+00567 <font class="comment"> //nldebug( "LNETL0: CSock::connected-END" );</font>
+00568 <font class="comment"> return b;*/</font>
+00569 <font class="keywordflow">return</font> _Connected;
+00570 }
+00571
+00572
+00573 <font class="comment">/*</font>
+00574 <font class="comment"> * Sets the socket in nonblocking mode</font>
+00575 <font class="comment"> */</font>
+00576 <font class="keywordtype">void</font> CSock::setNonBlockingMode ( <font class="keywordtype">bool</font> bm )
+00577 {
+00578 <font class="keywordflow">if</font> ( _NonBlocking != bm )
+00579 {
+00580 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font>
+00581 <font class="preprocessor"></font> u_long b = bm;
+00582 <font class="keywordflow">if</font> ( ioctlsocket( _Sock, FIONBIO, &amp;b ) != 0 )
+00583 <font class="preprocessor">#else</font>
+00584 <font class="preprocessor"></font> <font class="keywordflow">if</font> ( fcntl( _Sock, F_SETFL, FNDELAY | fcntl( _Sock, F_GETFL, 0 ) ) == -1 )
+00585 <font class="preprocessor">#endif</font>
+00586 <font class="preprocessor"></font> {
+00587 <font class="keywordflow">throw</font> ESocket( <font class="stringliteral">"Cannot set nonblocking mode"</font> );
+00588 }
+00589 _NonBlocking = bm;
+00590 }
+00591 }
+00592
+00593
+00594 } <font class="comment">// NLNET</font>
+</pre></div>
+
+<!-- footer -->
+<BR><FONT Size=+5>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </FONT>
+</TD>
+<TD WIDTH=15><IMG SRC=http://www.nevrax.org/inc/img/pixel.gif WIDTH=15 HEIGHT=15 BORDER=0 ALT=""></TD>
+</TR>
+</TABLE>
+</BODY>
+</HTML>