2 Copied from PLIB into SimGear
4 PLIB - A Suite of Portable Game Libraries
5 Copyright (C) 1998,2002 Steve Baker
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 For further information visit http://plib.sourceforge.net
23 $Id: netChannel.cxx 1906 2004-03-22 19:44:50Z sjbaker $
27 // have all socket-related functions assert that the socket has not
28 // been closed. [a read event may close it, and a write event may try
29 // to write or something...]
30 // Maybe assert valid handle, too?
32 #include "sg_netChannel.hxx"
38 #include <simgear/debug/logstream.hxx>
39 #include <simgear/io/HostLookup.hxx>
43 static NetChannel* channels = 0 ;
45 NetChannel::NetChannel ()
50 write_blocked = false ;
51 should_delete = false ;
53 next_channel = channels ;
57 NetChannel::~NetChannel ()
61 NetChannel* prev = NULL ;
63 for ( NetChannel* ch = channels; ch != NULL;
64 ch = ch -> next_channel )
68 ch = ch -> next_channel ;
70 prev -> next_channel = ch ;
81 NetChannel::setHandle (int handle, bool is_connected)
84 Socket::setHandle ( handle ) ;
85 connected = is_connected ;
86 //if ( connected ) this->handleConnect();
91 NetChannel::open (void)
94 if (Socket::open(true)) {
96 setBlocking ( false ) ;
103 NetChannel::listen ( int backlog )
106 return Socket::listen ( backlog ) ;
110 NetChannel::connect ( const char* host, int p )
112 host_lookup = HostLookup::lookup(host);
118 NetChannel::send (const void * buffer, int size, int flags)
120 int result = Socket::send (buffer, size, flags);
122 if (result == (int)size) {
123 // everything was sent
124 write_blocked = false ;
126 } else if (result >= 0) {
127 // not all of it was sent, but no error
128 write_blocked = true ;
130 } else if (isNonBlockingError ()) {
131 write_blocked = true ;
134 this->handleError (result);
142 NetChannel::recv (void * buffer, int size, int flags)
144 int result = Socket::recv (buffer, size, flags);
148 } else if (result == 0) {
151 } else if (isNonBlockingError ()) {
154 this->handleError (result);
161 NetChannel::close (void)
170 write_blocked = false ;
177 NetChannel::handleReadEvent (void)
182 //this->handleConnect();
184 this->handleAccept();
185 } else if (!connected) {
187 //this->handleConnect();
195 NetChannel::handleWriteEvent (void)
199 //this->handleConnect();
201 write_blocked = false ;
206 NetChannel::doConnect()
208 IPAddress addr( host_lookup->address() );
210 int result = Socket::connect ( addr ) ;
215 } else if (isNonBlockingError ()) {
218 // some other error condition
219 handleError (result);
225 NetChannel::poll (unsigned int timeout)
230 enum { MAX_SOCKETS = 256 } ;
231 Socket* reads [ MAX_SOCKETS+1 ] ;
232 Socket* writes [ MAX_SOCKETS+1 ] ;
233 Socket* deletes [ MAX_SOCKETS+1 ] ;
239 for ( ch = channels; ch != NULL; ch = ch -> next_channel )
241 if ( ch -> should_delete )
243 assert(ndeletes<MAX_SOCKETS);
244 deletes[ndeletes++] = ch ;
246 else if ( ! ch -> closed )
249 if (ch->host_lookup) {
250 if (ch->host_lookup->resolved()) {
252 } else if (ch->host_lookup->failed()) {
253 ch->handleError (-1);
259 if (ch -> readable()) {
260 assert(nreads<MAX_SOCKETS);
261 reads[nreads++] = ch ;
263 if (ch -> writable()) {
264 assert(nwrites<MAX_SOCKETS);
265 writes[nwrites++] = ch ;
269 reads[nreads] = NULL ;
270 writes[nwrites] = NULL ;
271 deletes[ndeletes] = NULL ;
274 for ( i=0; deletes[i]; i++ )
276 ch = (NetChannel*)deletes[i];
282 if (!nreads && !nwrites)
283 return true ; //hmmm- should we shutdown?
285 Socket::select (reads, writes, timeout) ;
287 for ( i=0; reads[i]; i++ )
289 ch = (NetChannel*)reads[i];
290 if ( ! ch -> closed )
291 ch -> handleReadEvent();
294 for ( i=0; writes[i]; i++ )
296 ch = (NetChannel*)writes[i];
297 if ( ! ch -> closed )
298 ch -> handleWriteEvent();
305 NetChannel::loop (unsigned int timeout)
307 while ( poll (timeout) ) ;
311 void NetChannel::handleRead (void) {
312 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled read");
315 void NetChannel::handleWrite (void) {
316 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled write");
319 void NetChannel::handleAccept (void) {
320 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled accept");
323 void NetChannel::handleError (int error) {
324 SG_LOG(SG_IO, SG_WARN,"Network:" << getHandle() << ": errno: " << strerror(errno) <<"(" << errno << ")");
327 } // of namespace simgear