X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fio%2Fsg_socket.hxx;h=4e1d9e0513e683025692ffc019c3cb7b3519c35e;hb=761b7b93543ad2e8dfd307ee3679b3a2a7082ddc;hp=c43a7c62e426a14ef54c67e77ea102db4e8ac58f;hpb=467254ec66069baca6a01e986924dd9ad6f74546;p=simgear.git diff --git a/simgear/io/sg_socket.hxx b/simgear/io/sg_socket.hxx index c43a7c62..4e1d9e05 100644 --- a/simgear/io/sg_socket.hxx +++ b/simgear/io/sg_socket.hxx @@ -1,5 +1,8 @@ -// 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 @@ -33,28 +36,21 @@ #include STL_STRING -#include +#include +#include -#include "iochannel.hxx" +#include -FG_USING_STD(string); - -#if defined(_MSC_VER) -# include -#endif +SG_USING_STD(string); #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; @@ -62,38 +58,82 @@ private: char save_buf[ 2 * SG_IO_MAX_MSG_SIZE ]; int save_len; - SocketType sock; - short unsigned int port; - int sock_style; // SOCK_STREAM or SOCK_DGRAM + netSocket sock; + netSocket* client; + unsigned short port; + bool is_tcp; + bool is_server; + bool first_read; + + 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: + /** + * 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 string& host, const string& port, const string& style ); + + /** Destructor */ ~SGSocket(); // 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,22 +142,26 @@ 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(); - // Enable non-blocking mode. + /** + * Enable non-blocking mode. + * @return success/failure + */ bool nonblock(); + /** @return the remote host name */ inline string get_hostname() const { return hostname; } + + /** @return the port number (in string form) */ inline string get_port_str() const { return port_str; } }; #endif // _SG_SOCKET_HXX - -