X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fio%2Fsg_socket.hxx;h=8341cb34b5aef1e7c2dda27463e6960e676aac0c;hb=403b7c14aaf57e3918636344d979a0190a21a4ab;hp=22915a2ae0c8e3faf1caa66f2a59ae479dc56353;hpb=5702bd7ee80b33840b95c8194d7887f45aaa5977;p=simgear.git diff --git a/simgear/io/sg_socket.hxx b/simgear/io/sg_socket.hxx index 22915a2a..8341cb34 100644 --- a/simgear/io/sg_socket.hxx +++ b/simgear/io/sg_socket.hxx @@ -1,8 +1,11 @@ -// sg_socket.hxx -- Socket I/O routines -// +/** + * \file sg_socket.hxx + * Socket I/O routines. + */ + // Written by Curtis Olson, started November 1999. // -// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org +// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -16,7 +19,7 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -24,73 +27,100 @@ #ifndef _SG_SOCKET_HXX #define _SG_SOCKET_HXX - -#ifndef __cplusplus -# error This library requires C++ -#endif - #include -#include STL_STRING +#include #include - -#include "iochannel.hxx" - -FG_USING_STD(string); - -#if defined(_MSC_VER) -# include -#endif +#include +#include #define SG_MAX_SOCKET_QUEUE 32 +/** + * A socket I/O class based on SGIOChannel. + */ class SGSocket : public SGIOChannel { public: -#if defined(_MSC_VER) - typedef SOCKET SocketType; -#else - typedef int SocketType; -# define INVALID_SOCKET (-1) -#endif - private: - string hostname; - string port_str; + std::string hostname; + std::string port_str; char save_buf[ 2 * SG_IO_MAX_MSG_SIZE ]; int save_len; - SocketType sock; - SocketType msgsock; - short unsigned int port; - int sock_style; // SOCK_STREAM or SOCK_DGRAM - + simgear::Socket sock; + simgear::Socket* client; + unsigned short port; + bool is_tcp; + bool is_server; bool first_read; + int timeout; + + static bool init; // make a server (master listening) socket - SocketType make_server_socket(); + bool make_server_socket(); // make a client socket - SocketType make_client_socket(); + bool make_client_socket(); - // wrapper functions - size_t readsocket( int fd, void *buf, size_t count ); - size_t writesocket( int fd, const void *buf, size_t count ); -#if !defined(_MSC_VER) - int closesocket(int fd); -#endif - -#if defined(_MSC_VER) - // Ensure winsock has been initialised. - static bool wsock_init; - static bool wsastartup(); -#endif + // Poll for new connections or data to read. + int poll(); public: - SGSocket( const string& host, const string& port, const string& style ); + /** + * Create an instance of SGSocket. + * + * When calling the constructor you need to provide a host name, a + * port number, and a socket style. The convention used by the + * SGSocket class is that the server side listens and the client + * side sends. For a server socket, the host name should be + * empty. For a server, the port number is optional, if you do not + * specify a port, the system will assign one. For a client + * socket, you need to specify both a destination host and + * destination port. For both client and server sockets you must + * specify the socket type. Type must be either udp or tcp. Here's + * a quick breakdown of the major differences between UDP and TCP + * type sockets. + * + * TCP sockets are the type where you establish a connection and + * then can read and write to the socket from both ends. If one + * end of TCP socket connect quits, the other end will likely + * segfault if it doesn't take special precautions. But, the nice + * thing about TCP connections is that the underlying protocol + * guarantees that your message will get through. This imposes a + * certain performance overhead though on the communication + * because the protocol must resend failed messages. TCP sockets + * are good for sending periodic command/response type messages + * where performance isn't a big issues, but reliability is. + * + * UDP sockets on the other hand are a lower level protocol and + * don't have the same sort of connection as TCP sockets. With UDP + * sockets, the server end just sits and listens for incoming + * packets from anywhere. The client end sends it's message and + * forgets about it. It doesn't care if there isn't even a server + * out there listening and all the packets are getting + * lost. Although systems/networks usually do a pretty good job + * (statistically) of getting your UDP packets to their + * destination, there is no guarantee that any particular packet + * will make it. But, because of this low level implementation and + * lack of error checking, UDP packets are much faster and + * efficient. UDP packets are good for sending positional + * information to synchronize two applications. In this case, you + * want the information to arrive as quickly as possible, and if + * you lose a packet, you'd rather get new updated information + * rather than have the system waste time resending a packet that + * is becoming older and older with every retry. + * @param host name of host if direction is SG_IO_OUT or SG_IO_BI + * @param port port number if we care to choose one. + * @param style specify "udp" or "tcp" + */ + SGSocket( const std::string& host, const std::string& port, const std::string& style ); + + /** Destructor */ ~SGSocket(); // If specified as a server (in direction for now) open the master @@ -113,14 +143,21 @@ public: // close file bool close(); - // Enable non-blocking mode. + /** + * Enable non-blocking mode. + * @return success/failure + */ bool nonblock(); - inline string get_hostname() const { return hostname; } - inline string get_port_str() const { return port_str; } -}; + // set timeout (default: 0) + inline void set_timeout(int i) { timeout = i; } + /** @return the remote host name */ + inline std::string get_hostname() const { return hostname; } -#endif // _SG_SOCKET_HXX + /** @return the port number (in string form) */ + inline std::string get_port_str() const { return port_str; } +}; +#endif // _SG_SOCKET_HXX