]> git.mxchange.org Git - simgear.git/commitdiff
io changes and tweaks. Working on adding SOCK_STREAM (tcp) support. Still
authorcurt <curt>
Wed, 4 Oct 2000 20:14:26 +0000 (20:14 +0000)
committercurt <curt>
Wed, 4 Oct 2000 20:14:26 +0000 (20:14 +0000)
needs some work, but is basically there.

simgear/io/Makefile.am
simgear/io/iochannel.cxx
simgear/io/iochannel.hxx
simgear/io/sg_file.cxx
simgear/io/sg_file.hxx
simgear/io/sg_serial.cxx
simgear/io/sg_serial.hxx
simgear/io/sg_socket.cxx
simgear/io/sg_socket.hxx

index 9e17a42447a715c26dbf6ba3576e43c8be52fb40..8752d3d79181e8b670053ea14a8990acd20947bc 100644 (file)
@@ -15,3 +15,11 @@ libsgio_a_SOURCES = \
        sg_socket.cxx 
 
 INCLUDES += -I$(top_srcdir)
+
+noinst_PROGRAMS = socktest
+
+socktest_SOURCES = socktest.cxx
+
+socktest_LDADD = \
+       $(top_builddir)/simgear/io/libsgio.a \
+       $(top_builddir)/simgear/debug/libsgdebug.a 
\ No newline at end of file
index ab83fc09711971e530b1891ab23e4e29bb6aba5a..ea8372cfc33112920b88f693c1fb191e12ba1a18 100644 (file)
@@ -39,7 +39,7 @@ SGIOChannel::~SGIOChannel()
 
 
 // dummy configure routine
-bool SGIOChannel::open( SGProtocolDir dir ) {
+bool SGIOChannel::open( const SGProtocolDir d ) {
     return false;
 }
 
@@ -57,13 +57,13 @@ int SGIOChannel::readline( char *buf, int length ) {
 
 
 // dummy process routine
-int SGIOChannel::write( char *buf, int length ) {
+int SGIOChannel::write( const char *buf, const int length ) {
     return false;
 }
 
 
 // dummy process routine
-int SGIOChannel::writestring( char *str ) {
+int SGIOChannel::writestring( const char *str ) {
     return false;
 }
 
index 941cdc0d378807621081bb5cf764884efbb1e37e..1d324be218417e88ab3c47dc89f8439e67833fbe 100644 (file)
@@ -55,21 +55,27 @@ enum SGChannelType {
 class SGIOChannel {
 
     SGChannelType type;
+    SGProtocolDir dir;
+    bool valid;
 
 public:
 
     SGIOChannel();
     virtual ~SGIOChannel();
 
-    virtual bool open( SGProtocolDir dir );
+    virtual bool open( const SGProtocolDir d );
     virtual int read( char *buf, int length );
     virtual int readline( char *buf, int length );
-    virtual int write( char *buf, int length );
-    virtual int writestring( char *str );
+    virtual int write( const char *buf, const int length );
+    virtual int writestring( const char *str );
     virtual bool close();
 
-    virtual void set_type( SGChannelType t ) { type = t; }
-    virtual SGChannelType get_type() const { return type; }
+    inline void set_type( SGChannelType t ) { type = t; }
+    inline SGChannelType get_type() const { return type; }
+
+    inline void set_dir( const SGProtocolDir d ) { dir = d; }
+    inline SGProtocolDir get_dir() const { return dir; }
+    inline bool isvalid() const { return valid; }
 };
 
 
index 055648c00e673942258db7002cb89ce0474a588c..912bcb6c3207b8a66fd6a3c17353276bca5fb8df 100644 (file)
@@ -47,15 +47,17 @@ SGFile::~SGFile() {
 
 
 // open the file based on specified direction
-bool SGFile::open( SGProtocolDir dir ) {
-    if ( dir == SG_IO_OUT ) {
+bool SGFile::open( const SGProtocolDir d ) {
+    set_dir( d );
+
+    if ( get_dir() == SG_IO_OUT ) {
 #ifdef _MSC_VER
         int mode = 00666;
 #else
         mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
 #endif
        fp = ::open( file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode );
-    } else if ( dir == SG_IO_IN ) {
+    } else if ( get_dir() == SG_IO_IN ) {
        fp = ::open( file_name.c_str(), O_RDONLY );
     } else {
        FG_LOG( FG_IO, FG_ALERT, 
@@ -105,7 +107,7 @@ int SGFile::readline( char *buf, int length ) {
 
 
 // write data to a file
-int SGFile::write( char *buf, int length ) {
+int SGFile::write( const char *buf, const int length ) {
     int result = ::write( fp, buf, length );
     if ( result != length ) {
        FG_LOG( FG_IO, FG_ALERT, "Error writing data: " << file_name );
@@ -116,7 +118,7 @@ int SGFile::write( char *buf, int length ) {
 
 
 // write null terminated string to a file
-int SGFile::writestring( char *str ) {
+int SGFile::writestring( const char *str ) {
     int length = strlen( str );
     return write( str, length );
 }
index b2618f28e051b16477552ae399291ec88afb6117..00d47143dc6ef47fc534e03082aec5dc208bfbda 100644 (file)
@@ -56,7 +56,7 @@ public:
     ~SGFile();
 
     // open the file based on specified direction
-    bool open( SGProtocolDir dir );
+    bool open( const SGProtocolDir dir );
 
     // read a block of data of specified size
     int read( char *buf, int length );
@@ -65,10 +65,10 @@ public:
     int readline( char *buf, int length );
 
     // write data to a file
-    int write( char *buf, int length );
+    int write( const char *buf, const int length );
 
     // write null terminated string to a file
-    int writestring( char *str );
+    int writestring( const char *str );
 
     // close file
     bool close();
index f59a98241c16e1cc326c81132d51261ce48bfb88..d174bcd203ab74b5f88e75435211cfff071a4e0b 100644 (file)
@@ -47,7 +47,9 @@ SGSerial::~SGSerial() {
 
 
 // open the serial port based on specified direction
-bool SGSerial::open( SGProtocolDir dir ) {
+bool SGSerial::open( const SGProtocolDir d ) {
+    set_dir( d );
+
     if ( ! port.open_port( device ) ) {
        FG_LOG( FG_IO, FG_ALERT, "Error opening device: " << device );
        return false;
@@ -127,7 +129,7 @@ int SGSerial::readline( char *buf, int length ) {
 
 
 // write data to port
-int SGSerial::write( char *buf, int length ) {
+int SGSerial::write( const char *buf, const int length ) {
     int result = port.write_port( buf, length );
 
     if ( result != length ) {
@@ -139,7 +141,7 @@ int SGSerial::write( char *buf, int length ) {
 
 
 // write null terminated string to port
-int SGSerial::writestring( char *str ) {
+int SGSerial::writestring( const char *str ) {
     int length = strlen( str );
     return write( str, length );
 }
index 43cb4433069860f8b5b74b2278cf1374676a377a..f5f7ad4f1de8e8b98108b6d191677d82dd294e08 100644 (file)
@@ -61,7 +61,7 @@ public:
     ~SGSerial();
 
     // open the serial port based on specified direction
-    bool open( SGProtocolDir dir );
+    bool open( const SGProtocolDir d );
 
     // read a block of data of specified size
     int read( char *buf, int length );
@@ -70,10 +70,10 @@ public:
     int readline( char *buf, int length );
 
     // write data to port
-    int write( char *buf, int length );
+    int write( const char *buf, const int length );
 
     // write null terminated string to port
-    int writestring( char *str );
+    int writestring( const char *str );
 
     // close port
     bool close();
index 288a4dd529a8e914c81be4b2bb0019e05726d547..c7f70200bfb54471596970ee76bcac8e40c9ecfa 100644 (file)
@@ -182,7 +182,9 @@ int SGSocket::closesocket( int fd ) {
 // If specified as a server (in direction for now) open the master
 // listening socket.  If specified as a client (out direction), open a
 // connection to a server.
-bool SGSocket::open( SGProtocolDir dir ) {
+bool SGSocket::open( const SGProtocolDir d ) {
+    set_dir( d );
+
     if ( port_str == "" || port_str == "any" ) {
        port = 0; 
     } else {
@@ -191,14 +193,17 @@ bool SGSocket::open( SGProtocolDir dir ) {
     
     // client_connections.clear();
 
-    if ( dir == SG_IO_IN ) {
+    if ( get_dir() == SG_IO_IN ) {
        // this means server for now
 
        // Setup socket to listen on.  Set "port" before making this
        // call.  A port of "0" indicates that we want to let the os
        // pick any available port.
        sock = make_server_socket();
-       // TODO: check for error.
+       if ( sock == INVALID_SOCKET ) {
+           FG_LOG( FG_IO, FG_ALERT, "socket creation failed" );
+           return false;
+       }
 
        FG_LOG( FG_IO, FG_INFO, "socket is connected to port = " << port );
 
@@ -211,7 +216,7 @@ bool SGSocket::open( SGProtocolDir dir ) {
            listen( sock, SG_MAX_SOCKET_QUEUE );
        }
 
-    } else if ( dir == SG_IO_OUT ) {
+    } else if ( get_dir() == SG_IO_OUT ) {
        // this means client for now
 
        sock = make_client_socket();
@@ -221,7 +226,7 @@ bool SGSocket::open( SGProtocolDir dir ) {
            // Non-blocking UDP
            nonblock();
        }
-    } else if ( dir == SG_IO_BI && sock_style == SOCK_STREAM ) {
+    } else if ( get_dir() == SG_IO_BI && sock_style == SOCK_STREAM ) {
        // this means server for TCP sockets
 
        // Setup socket to listen on.  Set "port" before making this
@@ -247,6 +252,10 @@ bool SGSocket::open( SGProtocolDir dir ) {
        return false;
     }
 
+    // extra SOCK_STREAM stuff
+    msgsock = INVALID_SOCKET;
+    first_read = false;
+
     return true;
 }
 
@@ -254,8 +263,11 @@ bool SGSocket::open( SGProtocolDir dir ) {
 // read data from socket (server)
 // read a block of data of specified size
 int SGSocket::read( char *buf, int length ) {
-    int result = 0;
+    if ( sock == INVALID_SOCKET ) {
+       return 0;
+    }
 
+    int result = 0;
     // check for potential input
     fd_set ready;
     FD_ZERO(&ready);
@@ -269,7 +281,20 @@ int SGSocket::read( char *buf, int length ) {
     select(32, &ready, 0, 0, &tv);
 
     if ( FD_ISSET(sock, &ready) ) {
-       result = readsocket( sock, buf, length );
+       // cout << "data ready" << endl;
+
+       if ( sock_style == SOCK_STREAM ) {
+           if ( msgsock == INVALID_SOCKET ) {
+               msgsock = accept(sock, 0, 0);
+               closesocket(sock);
+               sock = msgsock;
+           } else {
+               result = readsocket( sock, buf, length );
+           }
+       } else {
+           result = readsocket( sock, buf, length );
+       }
+
        if ( result != length ) {
            FG_LOG( FG_IO, FG_INFO, 
                    "Warning: read() not enough bytes." );
@@ -282,7 +307,11 @@ int SGSocket::read( char *buf, int length ) {
 
 // read a line of data, length is max size of input buffer
 int SGSocket::readline( char *buf, int length ) {
-    int result = 0;
+    if ( sock == INVALID_SOCKET ) {
+       return 0;
+    }
+
+    // cout << "sock = " << sock << endl;
 
     // check for potential input
     fd_set ready;
@@ -294,19 +323,55 @@ int SGSocket::readline( char *buf, int length ) {
 
     // test for any input read on sock (returning immediately, even if
     // nothing)
-    int rc = select(32, &ready, 0, 0, &tv);
-    // FG_LOG( FG_IO, FG_DEBUG, "select returned " << rc );
+    int result = select(32, &ready, 0, 0, &tv);
+    // cout << "result = " << result << endl;
 
     if ( FD_ISSET(sock, &ready) ) {
+       // cout << "fd change state\n";
        // read a chunk, keep in the save buffer until we have the
        // requested amount read
 
-       char *buf_ptr = save_buf + save_len;
-       result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
-       save_len += result;
+       if ( sock_style == SOCK_STREAM ) {
+           // cout << "sock_stream\n";
+           if ( msgsock == INVALID_SOCKET ) {
+               // cout << "msgsock == invalid\n";
+               msgsock = accept(sock, 0, 0);
+               closesocket(sock);
+               sock = msgsock;
+           } else {
+               // cout << "ready to read\n";
+               char *buf_ptr = save_buf + save_len;
+               result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE
+                                    - save_len );
+               // cout << "read result = " << result << endl;
+
+               if ( result > 0 ) {
+                   first_read = true;
+               }
+
+               save_len += result;
+
+               // Try and detect that the remote end died.  This
+               // could cause problems so if you see connections
+               // dropping for unexplained reasons, LOOK HERE!
+               if ( result == 0 && save_len == 0 && first_read == true ) {
+                   FG_LOG( FG_IO, FG_ALERT, 
+                           "Connection closed by foreign host." );
+                   closesocket(sock);
+                   open( get_dir() );
+               }
+           }
+       } else {
+           char *buf_ptr = save_buf + save_len;
+           result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
+           save_len += result;
+       }
+
        // cout << "current read = " << buf_ptr << endl;
        // cout << "current save_buf = " << save_buf << endl;
        // cout << "save_len = " << save_len << endl;
+    } else {
+       // cout << "no data ready\n";
     }
 
     // look for the end of line in save_buf
@@ -339,7 +404,11 @@ int SGSocket::readline( char *buf, int length ) {
 
 
 // write data to socket (client)
-int SGSocket::write( char *buf, int length ) {
+int SGSocket::write( const char *buf, const int length ) {
+    if ( sock == INVALID_SOCKET ) {
+       return 0;
+    }
+
     bool error_condition = false;
 
     if ( writesocket(sock, buf, length) < 0 ) {
@@ -404,7 +473,11 @@ int SGSocket::write( char *buf, int length ) {
 
 
 // write null terminated string to socket (server)
-int SGSocket::writestring( char *str ) {
+int SGSocket::writestring( const char *str ) {
+    if ( sock == INVALID_SOCKET ) {
+       return 0;
+    }
+
     int length = strlen( str );
     return write( str, length );
 }
@@ -412,12 +485,9 @@ int SGSocket::writestring( char *str ) {
 
 // close the port
 bool SGSocket::close() {
-#if 0
-    for ( int i = 0; i < (int)client_connections.size(); ++i ) {
-       int msgsock = client_connections[i];
-       closesocket( msgsock );
+    if ( sock == INVALID_SOCKET ) {
+       return 0;
     }
-#endif
 
     closesocket( sock );
     return true;
@@ -426,6 +496,10 @@ bool SGSocket::close() {
 
 // configure the socket as non-blocking
 bool SGSocket::nonblock() {
+    if ( sock == INVALID_SOCKET ) {
+       return 0;
+    }
+
 #if defined(_MSC_VER)
     u_long arg = 1;
     if (ioctlsocket( sock, FIONBIO, &arg ) != 0) {
index e775eb3b936ac5d60a37a0d6aeb666655e59e71e..22915a2ae0c8e3faf1caa66f2a59ae479dc56353 100644 (file)
@@ -63,9 +63,12 @@ private:
     int save_len;
 
     SocketType sock;
+    SocketType msgsock;
     short unsigned int port;
     int sock_style;                    // SOCK_STREAM or SOCK_DGRAM
 
+    bool first_read;
+
     // make a server (master listening) socket
     SocketType make_server_socket();
 
@@ -93,7 +96,7 @@ public:
     // If specified as a server (in direction for now) open the master
     // listening socket.  If specified as a client (out direction),
     // open a connection to a server.
-    bool open( SGProtocolDir dir );
+    bool open( const SGProtocolDir d );
 
     // read data from socket
     int read( char *buf, int length );
@@ -102,10 +105,10 @@ public:
     int readline( char *buf, int length );
 
     // write data to a socket
-    int write( char *buf, int length );
+    int write( const char *buf, const int length );
 
     // write null terminated string to a socket
-    int writestring( char *str );
+    int writestring( const char *str );
 
     // close file
     bool close();