]> git.mxchange.org Git - simgear.git/blob - simgear/io/sg_socket_udp.cxx
Merge branch 'fredb/effect-stuff'
[simgear.git] / simgear / io / sg_socket_udp.cxx
1 // sg_socket.cxx -- Socket I/O routines
2 //
3 // Written by Curtis Olson, started November 1999.
4 //
5 // Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23 #ifdef HAVE_CONFIG_H
24 #  include <simgear_config.h>
25 #endif
26
27 #include <simgear/compiler.h>
28
29 #if defined( sgi )
30 #include <strings.h>
31 #endif
32
33 #include <simgear/debug/logstream.hxx>
34
35 #include "sg_socket_udp.hxx"
36
37
38 SGSocketUDP::SGSocketUDP( const string& host, const string& port ) :
39     hostname(host),
40     port_str(port),
41     save_len(0)
42 {
43     set_valid( false );
44 }
45
46
47 SGSocketUDP::~SGSocketUDP() {
48 }
49
50
51 // If specified as a server (in direction for now) open the master
52 // listening socket.  If specified as a client (out direction), open a
53 // connection to a server.
54 bool SGSocketUDP::open( const SGProtocolDir d ) {
55     set_dir( d );
56
57     if ( ! sock.open( false ) ) {       // open a UDP socket
58         SG_LOG( SG_IO, SG_ALERT, "error opening socket" );
59         return false;
60     }
61
62     if ( port_str == "" || port_str == "any" ) {
63         port = 0; 
64     } else {
65         port = atoi( port_str.c_str() );
66     }
67     
68     // client_connections.clear();
69
70     if ( get_dir() == SG_IO_IN ) {
71         // this means server
72
73         // bind ...
74         if ( sock.bind( hostname.c_str(), port ) == -1 ) {
75             SG_LOG( SG_IO, SG_ALERT, "error binding to port" << port_str );
76             return false;
77         }
78     } else if ( get_dir() == SG_IO_OUT ) {
79         // this means client
80
81         // connect ...
82         if ( sock.connect( hostname.c_str(), port ) == -1 ) {
83             SG_LOG( SG_IO, SG_ALERT,
84                     "error connecting to " << hostname << port_str );
85             return false;
86         }
87     } else {
88         SG_LOG( SG_IO, SG_ALERT, 
89                 "Error:  bidirection mode not available for UDP sockets." );
90         return false;
91     }
92
93     set_valid( true );
94
95     return true;
96 }
97
98
99 // read data from socket (server)
100 // read a block of data of specified size
101 int SGSocketUDP::read( char *buf, int length ) {
102     if ( ! isvalid() ) {
103         return 0;
104     }
105
106     int result;
107
108     if ( (result = sock.recv(buf, SG_IO_MAX_MSG_SIZE, 0)) >= 0 ) {
109         buf[result] = '\0';
110         // printf("msg received = %s\n", buf);
111     }
112
113     return result;
114 }
115
116
117 // read a line of data, length is max size of input buffer
118 int SGSocketUDP::readline( char *buf, int length ) {
119     if ( ! isvalid() ) {
120         return 0;
121     }
122
123     // cout << "sock = " << sock << endl;
124
125     char *buf_ptr = save_buf + save_len;
126     int result = sock.recv(buf_ptr, SG_IO_MAX_MSG_SIZE, 0);
127     // printf("msg received = %s\n", buf);
128     save_len += result;
129
130     // look for the end of line in save_buf
131     int i;
132     for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i );
133     if ( save_buf[i] == '\n' ) {
134         result = i + 1;
135     } else {
136         // no end of line yet
137         // cout << "no eol found" << endl;
138         return 0;
139     }
140     // cout << "line length = " << result << endl;
141
142     // we found an end of line
143
144     // copy to external buffer
145     strncpy( buf, save_buf, result );
146     buf[result] = '\0';
147     // cout << "sg_socket line = " << buf << endl;
148     
149     // shift save buffer
150     for ( i = result; i < save_len; ++i ) {
151         save_buf[ i - result ] = save_buf[i];
152     }
153     save_len -= result;
154
155     return result;
156 }
157
158
159 // write data to socket (client)
160 int SGSocketUDP::write( const char *buf, const int length ) {
161     if ( ! isvalid() ) {
162         return 0;
163     }
164
165     bool error_condition = false;
166
167     if ( sock.send( buf, length, 0 ) < 0 ) {
168         SG_LOG( SG_IO, SG_WARN, "Error writing to socket: " << port );
169         error_condition = true;
170         return 0;
171     }
172
173     return length;
174 }
175
176
177 // write null terminated string to socket (server)
178 int SGSocketUDP::writestring( const char *str ) {
179     if ( !isvalid() ) {
180         return 0;
181     }
182
183     int length = strlen( str );
184     return write( str, length );
185 }
186
187
188 // close the port
189 bool SGSocketUDP::close() {
190     if ( !isvalid() ) {
191         return 0;
192     }
193
194     sock.close();
195
196     return true;
197 }
198
199
200 // configure the socket as non-blocking
201 bool SGSocketUDP::setBlocking( bool value ) {
202     sock.setBlocking( value );
203
204     return true;
205 }