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"
36 #include <simgear/debug/logstream.hxx>
40 static NetChannel* channels = 0 ;
42 NetChannel::NetChannel ()
47 write_blocked = false ;
48 should_delete = false ;
50 next_channel = channels ;
54 NetChannel::~NetChannel ()
58 NetChannel* prev = NULL ;
60 for ( NetChannel* ch = channels; ch != NULL;
61 ch = ch -> next_channel )
65 ch = ch -> next_channel ;
67 prev -> next_channel = ch ;
78 NetChannel::setHandle (int handle, bool is_connected)
81 Socket::setHandle ( handle ) ;
82 connected = is_connected ;
83 //if ( connected ) this->handleConnect();
88 NetChannel::open (void)
91 if (Socket::open(true)) {
93 setBlocking ( false ) ;
100 NetChannel::listen ( int backlog )
103 return Socket::listen ( backlog ) ;
107 NetChannel::connect ( const char* host, int port )
109 int result = Socket::connect ( host, port ) ;
112 //this->handleConnect();
114 } else if (isNonBlockingError ()) {
117 // some other error condition
118 this->handleError (result);
125 NetChannel::send (const void * buffer, int size, int flags)
127 int result = Socket::send (buffer, size, flags);
129 if (result == (int)size) {
130 // everything was sent
131 write_blocked = false ;
133 } else if (result >= 0) {
134 // not all of it was sent, but no error
135 write_blocked = true ;
137 } else if (isNonBlockingError ()) {
138 write_blocked = true ;
141 this->handleError (result);
149 NetChannel::recv (void * buffer, int size, int flags)
151 int result = Socket::recv (buffer, size, flags);
155 } else if (result == 0) {
158 } else if (isNonBlockingError ()) {
161 this->handleError (result);
168 NetChannel::close (void)
177 write_blocked = false ;
184 NetChannel::handleReadEvent (void)
189 //this->handleConnect();
191 this->handleAccept();
192 } else if (!connected) {
194 //this->handleConnect();
202 NetChannel::handleWriteEvent (void)
206 //this->handleConnect();
208 write_blocked = false ;
213 NetChannel::poll (unsigned int timeout)
218 enum { MAX_SOCKETS = 256 } ;
219 Socket* reads [ MAX_SOCKETS+1 ] ;
220 Socket* writes [ MAX_SOCKETS+1 ] ;
221 Socket* deletes [ MAX_SOCKETS+1 ] ;
227 for ( ch = channels; ch != NULL; ch = ch -> next_channel )
229 if ( ch -> should_delete )
231 assert(ndeletes<MAX_SOCKETS);
232 deletes[ndeletes++] = ch ;
234 else if ( ! ch -> closed )
237 if (ch -> readable()) {
238 assert(nreads<MAX_SOCKETS);
239 reads[nreads++] = ch ;
241 if (ch -> writable()) {
242 assert(nwrites<MAX_SOCKETS);
243 writes[nwrites++] = ch ;
247 reads[nreads] = NULL ;
248 writes[nwrites] = NULL ;
249 deletes[ndeletes] = NULL ;
252 for ( i=0; deletes[i]; i++ )
254 ch = (NetChannel*)deletes[i];
260 if (!nreads && !nwrites)
261 return true ; //hmmm- should we shutdown?
263 Socket::select (reads, writes, timeout) ;
265 for ( i=0; reads[i]; i++ )
267 ch = (NetChannel*)reads[i];
268 if ( ! ch -> closed )
269 ch -> handleReadEvent();
272 for ( i=0; writes[i]; i++ )
274 ch = (NetChannel*)writes[i];
275 if ( ! ch -> closed )
276 ch -> handleWriteEvent();
283 NetChannel::loop (unsigned int timeout)
285 while ( poll (timeout) ) ;
289 void NetChannel::handleRead (void) {
290 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled read");
293 void NetChannel::handleWrite (void) {
294 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled write");
297 void NetChannel::handleAccept (void) {
298 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled accept");
301 void NetChannel::handleError (int error) {
302 SG_LOG(SG_IO, SG_WARN,"Network:" << getHandle() << ": errno: " << strerror(errno) <<"(" << errno << ")");
305 } // of namespace simgear