]> git.mxchange.org Git - simgear.git/blob - simgear/io/sg_socket_udp.cxx
Linux build fixes, now netSocket.h is no longer included.
[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 #include <simgear/debug/logstream.hxx>
30
31 #include "sg_socket_udp.hxx"
32
33 #include <cstring>
34 #include <cstdlib> // for atoi
35
36 SGSocketUDP::SGSocketUDP( const string& host, const string& port ) :
37     hostname(host),
38     port_str(port),
39     save_len(0)
40 {
41     set_valid( false );
42 }
43
44
45 SGSocketUDP::~SGSocketUDP() {
46 }
47
48
49 // If specified as a server (in direction for now) open the master
50 // listening socket.  If specified as a client (out direction), open a
51 // connection to a server.
52 bool SGSocketUDP::open( const SGProtocolDir d ) {
53     set_dir( d );
54
55     if ( ! sock.open( false ) ) {       // open a UDP socket
56         SG_LOG( SG_IO, SG_ALERT, "error opening socket" );
57         return false;
58     }
59
60     if ( port_str == "" || port_str == "any" ) {
61         port = 0; 
62     } else {
63         port = atoi( port_str.c_str() );
64     }
65     
66     // client_connections.clear();
67
68     if ( get_dir() == SG_IO_IN ) {
69         // this means server
70
71         // bind ...
72         if ( sock.bind( hostname.c_str(), port ) == -1 ) {
73             SG_LOG( SG_IO, SG_ALERT, "error binding to port" << port_str );
74             return false;
75         }
76     } else if ( get_dir() == SG_IO_OUT ) {
77         // this means client
78
79         // connect ...
80         if ( sock.connect( hostname.c_str(), port ) == -1 ) {
81             SG_LOG( SG_IO, SG_ALERT,
82                     "error connecting to " << hostname << port_str );
83             return false;
84         }
85     } else {
86         SG_LOG( SG_IO, SG_ALERT, 
87                 "Error:  bidirection mode not available for UDP sockets." );
88         return false;
89     }
90
91     set_valid( true );
92
93     return true;
94 }
95
96
97 // read data from socket (server)
98 // read a block of data of specified size
99 int SGSocketUDP::read( char *buf, int length ) {
100     if ( ! isvalid() ) {
101         return 0;
102     }
103
104     int result;
105
106     if ( (result = sock.recv(buf, SG_IO_MAX_MSG_SIZE, 0)) >= 0 ) {
107         buf[result] = '\0';
108         // printf("msg received = %s\n", buf);
109     }
110
111     return result;
112 }
113
114
115 // read a line of data, length is max size of input buffer
116 int SGSocketUDP::readline( char *buf, int length ) {
117     if ( ! isvalid() ) {
118         return 0;
119     }
120
121     // cout << "sock = " << sock << endl;
122
123     char *buf_ptr = save_buf + save_len;
124     int result = sock.recv(buf_ptr, SG_IO_MAX_MSG_SIZE, 0);
125     // printf("msg received = %s\n", buf);
126     save_len += result;
127
128     // look for the end of line in save_buf
129     int i;
130     for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i );
131     if ( save_buf[i] == '\n' ) {
132         result = i + 1;
133     } else {
134         // no end of line yet
135         // cout << "no eol found" << endl;
136         return 0;
137     }
138     // cout << "line length = " << result << endl;
139
140     // we found an end of line
141
142     // copy to external buffer
143     strncpy( buf, save_buf, result );
144     buf[result] = '\0';
145     // cout << "sg_socket line = " << buf << endl;
146     
147     // shift save buffer
148     for ( i = result; i < save_len; ++i ) {
149         save_buf[ i - result ] = save_buf[i];
150     }
151     save_len -= result;
152
153     return result;
154 }
155
156
157 // write data to socket (client)
158 int SGSocketUDP::write( const char *buf, const int length ) {
159     if ( ! isvalid() ) {
160         return 0;
161     }
162
163     bool error_condition = false;
164
165     if ( sock.send( buf, length, 0 ) < 0 ) {
166         SG_LOG( SG_IO, SG_WARN, "Error writing to socket: " << port );
167         error_condition = true;
168         return 0;
169     }
170
171     return length;
172 }
173
174
175 // write null terminated string to socket (server)
176 int SGSocketUDP::writestring( const char *str ) {
177     if ( !isvalid() ) {
178         return 0;
179     }
180
181     int length = strlen( str );
182     return write( str, length );
183 }
184
185
186 // close the port
187 bool SGSocketUDP::close() {
188     if ( !isvalid() ) {
189         return 0;
190     }
191
192     sock.close();
193
194     return true;
195 }
196
197
198 // configure the socket as non-blocking
199 bool SGSocketUDP::setBlocking( bool value ) {
200     sock.setBlocking( value );
201
202     return true;
203 }