00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 # include <simgear_config.h>
00025 #endif
00026
00027 #include <simgear/compiler.h>
00028
00029 #if defined( sgi )
00030 #include <strings.h>
00031 #endif
00032
00033 #include <simgear/debug/logstream.hxx>
00034
00035 #include "sg_socket_udp.hxx"
00036
00037
00038 SGSocketUDP::SGSocketUDP( const string& host, const string& port ) :
00039 hostname(host),
00040 port_str(port),
00041 save_len(0)
00042 {
00043 set_valid( false );
00044 }
00045
00046
00047 SGSocketUDP::~SGSocketUDP() {
00048 }
00049
00050
00051
00052
00053
00054 bool SGSocketUDP::open( const SGProtocolDir d ) {
00055 set_dir( d );
00056
00057 if ( ! sock.open( false ) ) {
00058 SG_LOG( SG_IO, SG_ALERT, "error opening socket" );
00059 return false;
00060 }
00061
00062 if ( port_str == "" || port_str == "any" ) {
00063 port = 0;
00064 } else {
00065 port = atoi( port_str.c_str() );
00066 }
00067
00068
00069
00070 if ( get_dir() == SG_IO_IN ) {
00071
00072
00073
00074 if ( sock.bind( hostname.c_str(), port ) == -1 ) {
00075 SG_LOG( SG_IO, SG_ALERT, "error binding to port" << port_str );
00076 return false;
00077 }
00078 } else if ( get_dir() == SG_IO_OUT ) {
00079
00080
00081
00082 if ( sock.connect( hostname.c_str(), port ) == -1 ) {
00083 SG_LOG( SG_IO, SG_ALERT,
00084 "error connecting to " << hostname << port_str );
00085 return false;
00086 }
00087 } else {
00088 SG_LOG( SG_IO, SG_ALERT,
00089 "Error: bidirection mode not available for UDP sockets." );
00090 return false;
00091 }
00092
00093 set_valid( true );
00094
00095 return true;
00096 }
00097
00098
00099
00100
00101 int SGSocketUDP::read( char *buf, int length ) {
00102 if ( ! isvalid() ) {
00103 return 0;
00104 }
00105
00106 int result;
00107
00108 if ( (result = sock.recv(buf, SG_IO_MAX_MSG_SIZE, 0)) >= 0 ) {
00109 buf[result] = '\0';
00110
00111 }
00112
00113 return result;
00114 }
00115
00116
00117
00118 int SGSocketUDP::readline( char *buf, int length ) {
00119 if ( ! isvalid() ) {
00120 return 0;
00121 }
00122
00123
00124
00125 char *buf_ptr = save_buf + save_len;
00126 int result = sock.recv(buf_ptr, SG_IO_MAX_MSG_SIZE, 0);
00127
00128 save_len += result;
00129
00130
00131 int i;
00132 for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i );
00133 if ( save_buf[i] == '\n' ) {
00134 result = i + 1;
00135 } else {
00136
00137
00138 return 0;
00139 }
00140
00141
00142
00143
00144
00145 strncpy( buf, save_buf, result );
00146 buf[result] = '\0';
00147
00148
00149
00150 for ( i = result; i < save_len; ++i ) {
00151 save_buf[ i - result ] = save_buf[i];
00152 }
00153 save_len -= result;
00154
00155 return result;
00156 }
00157
00158
00159
00160 int SGSocketUDP::write( const char *buf, const int length ) {
00161 if ( ! isvalid() ) {
00162 return 0;
00163 }
00164
00165 bool error_condition = false;
00166
00167 if ( sock.send( buf, length, 0 ) < 0 ) {
00168 SG_LOG( SG_IO, SG_WARN, "Error writing to socket: " << port );
00169 error_condition = true;
00170 return 0;
00171 }
00172
00173 return length;
00174 }
00175
00176
00177
00178 int SGSocketUDP::writestring( const char *str ) {
00179 if ( !isvalid() ) {
00180 return 0;
00181 }
00182
00183 int length = strlen( str );
00184 return write( str, length );
00185 }
00186
00187
00188
00189 bool SGSocketUDP::close() {
00190 if ( !isvalid() ) {
00191 return 0;
00192 }
00193
00194 sock.close();
00195
00196 return true;
00197 }
00198
00199
00200
00201 bool SGSocketUDP::setBlocking( bool value ) {
00202 sock.setBlocking( value );
00203
00204 return true;
00205 }