head 1.4; access; symbols; locks; strict; comment @# @; 1.4 date 2002.09.07.01.50.40; author curt; state Exp; branches; next 1.3; 1.3 date 2002.08.31.19.01.57; author curt; state Exp; branches; next 1.2; 1.2 date 2002.08.31.18.54.04; author curt; state Exp; branches; next 1.1; 1.1 date 2002.02.15.17.22.01; author curt; state Exp; branches; next ; desc @@ 1.4 log @Updated doxygen docs. @ text @
Main Page Class Hierarchy Compound List File List Compound Members File Members

# sg_socket_udp.cxx

    00001 // sg_socket.cxx -- Socket I/O routines
    00002 //
    00003 // Written by Curtis Olson, started November 1999.
    00004 //
    00005 // Copyright (C) 1999  Curtis L. Olson - curt@@flightgear.org
    00006 //
    00007 // This program is free software; you can redistribute it and/or
    00008 // modify it under the terms of the GNU General Public License as
    00009 // published by the Free Software Foundation; either version 2 of the
    00010 // License, or (at your option) any later version.
    00011 //
    00012 // This program is distributed in the hope that it will be useful, but
    00013 // WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015 // General Public License for more details.
    00016 //
    00017 // You should have received a copy of the GNU General Public License
    00018 // along with this program; if not, write to the Free Software
    00019 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00020 //
    00021 // $Id: sg_socket_udp.cxx,v 1.1 2001/11/12 04:47:59 curt Exp $
    00022
    00023
    00024 #include <simgear/compiler.h>
    00025
    00026 #if defined( sgi )
    00027 #include <strings.h>
    00028 #endif
    00029
    00030 #include <simgear/debug/logstream.hxx>
    00031
    00032 #include "sg_socket_udp.hxx"
    00033
    00034
    00035 SGSocketUDP::SGSocketUDP( const string& host, const string& port ) :
    00036     hostname(host),
    00037     port_str(port),
    00038     save_len(0)
    00039 {
    00040     set_valid( false );
    00041 }
    00042
    00043
    00044 SGSocketUDP::~SGSocketUDP() {
    00045 }
    00046
    00047
    00048 // If specified as a server (in direction for now) open the master
    00049 // listening socket.  If specified as a client (out direction), open a
    00050 // connection to a server.
    00051 bool SGSocketUDP::open( const SGProtocolDir d ) {
    00052     set_dir( d );
    00053
    00054     if ( ! sock.open( false ) ) {       // open a UDP socket
    00055         SG_LOG( SG_IO, SG_ALERT, "error opening socket" );
    00056         return false;
    00057     }
    00058
    00059     if ( port_str == "" || port_str == "any" ) {
    00060         port = 0;
    00061     } else {
    00062         port = atoi( port_str.c_str() );
    00063     }
    00064
    00065     // client_connections.clear();
    00066
    00067     if ( get_dir() == SG_IO_IN ) {
    00068         // this means server
    00069
    00070         // bind ...
    00071         if ( sock.bind( hostname.c_str(), port ) == -1 ) {
    00072             SG_LOG( SG_IO, SG_ALERT, "error binding to port" << port_str );
    00073             return false;
    00074         }
    00075     } else if ( get_dir() == SG_IO_OUT ) {
    00076         // this means client
    00077
    00078         // connect ...
    00079         if ( sock.connect( hostname.c_str(), port ) == -1 ) {
    00080             SG_LOG( SG_IO, SG_ALERT,
    00081                     "error connecting to " << hostname << port_str );
    00082             return false;
    00083         }
    00084     } else {
    00085         SG_LOG( SG_IO, SG_ALERT,
    00086                 "Error:  bidirection mode not available for UDP sockets." );
    00087         return false;
    00088     }
    00089
    00090     set_valid( true );
    00091
    00092     return true;
    00093 }
    00094
    00095
    00096 // read data from socket (server)
    00097 // read a block of data of specified size
    00098 int SGSocketUDP::read( char *buf, int length ) {
    00099     if ( ! isvalid() ) {
    00100         return 0;
    00101     }
    00102
    00103     int result;
    00104
    00105     if ( (result = sock.recv(buf, SG_IO_MAX_MSG_SIZE, 0)) >= 0 ) {
    00106         buf[result] = '\0';
    00107         // printf("msg received = %s\n", buf);
    00108     }
    00109
    00110     return result;
    00111 }
    00112
    00113
    00114 // read a line of data, length is max size of input buffer
    00115 int SGSocketUDP::readline( char *buf, int length ) {
    00116     if ( ! isvalid() ) {
    00117         return 0;
    00118     }
    00119
    00120     // cout << "sock = " << sock << endl;
    00121
    00122     char *buf_ptr = save_buf + save_len;
    00123     int result = sock.recv(buf_ptr, SG_IO_MAX_MSG_SIZE, 0);
    00124     // printf("msg received = %s\n", buf);
    00125     save_len += result;
    00126
    00127     // look for the end of line in save_buf
    00128     int i;
    00129     for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i );
    00130     if ( save_buf[i] == '\n' ) {
    00131         result = i + 1;
    00132     } else {
    00133         // no end of line yet
    00134         // cout << "no eol found" << endl;
    00135         return 0;
    00136     }
    00137     // cout << "line length = " << result << endl;
    00138
    00139     // we found an end of line
    00140
    00141     // copy to external buffer
    00142     strncpy( buf, save_buf, result );
    00143     buf[result] = '\0';
    00144     // cout << "sg_socket line = " << buf << endl;
    00145
    00146     // shift save buffer
    00147     for ( i = result; i < save_len; ++i ) {
    00148         save_buf[ i - result ] = save_buf[i];
    00149     }
    00150     save_len -= result;
    00151
    00152     return result;
    00153 }
    00154
    00155
    00156 // write data to socket (client)
    00157 int SGSocketUDP::write( const char *buf, const int length ) {
    00158     if ( ! isvalid() ) {
    00159         return 0;
    00160     }
    00161
    00162     bool error_condition = false;
    00163
    00164     if ( sock.send( buf, length, 0 ) < 0 ) {
    00165         SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
    00166         error_condition = true;
    00167         return 0;
    00168     }
    00169
    00170     return length;
    00171 }
    00172
    00173
    00174 // write null terminated string to socket (server)
    00175 int SGSocketUDP::writestring( const char *str ) {
    00176     if ( !isvalid() ) {
    00177         return 0;
    00178     }
    00179
    00180     int length = strlen( str );
    00181     return write( str, length );
    00182 }
    00183
    00184
    00185 // close the port
    00186 bool SGSocketUDP::close() {
    00187     if ( !isvalid() ) {
    00188         return 0;
    00189     }
    00190
    00191     sock.close();
    00192
    00193     return true;
    00194 }
    00195
    00196
    00197 // configure the socket as non-blocking
    00198 bool SGSocketUDP::setBlocking( bool value ) {
    00199     sock.setBlocking( value );
    00200
    00201     return true;
    00202 }

@ 1.3 log @Oops, try again. @ text @d211 1 a211 1