initial commit
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
387
libs/wxWidgets-3.3.1/include/wx/private/socket.h
Normal file
387
libs/wxWidgets-3.3.1/include/wx/private/socket.h
Normal file
@@ -0,0 +1,387 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/private/socket.h
|
||||
// Purpose: wxSocketImpl and related declarations
|
||||
// Authors: Guilhem Lavaux, Vadim Zeitlin
|
||||
// Created: April 1997
|
||||
// Copyright: (c) 1997 Guilhem Lavaux
|
||||
// (c) 2008 Vadim Zeitlin
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
Brief overview of different socket classes:
|
||||
|
||||
- wxSocketBase is the public class representing a socket ("Base" here
|
||||
refers to the fact that wxSocketClient and wxSocketServer are derived
|
||||
from it and predates the convention of using "Base" for common base
|
||||
classes for platform-specific classes in wxWidgets) with implementation
|
||||
common to all platforms and forwarding methods whose implementation
|
||||
differs between platforms to wxSocketImpl which it contains.
|
||||
|
||||
- wxSocketImpl is actually just an abstract base class having only code
|
||||
common to all platforms, the concrete implementation classes derive from
|
||||
it and are created by wxSocketImpl::Create().
|
||||
|
||||
- Some socket operations have different implementations in console-mode and
|
||||
GUI applications. wxSocketManager class exists to abstract this in such
|
||||
way that console applications (using wxBase) don't depend on wxNet. An
|
||||
object of this class is made available via wxApp and GUI applications set
|
||||
up a different kind of global socket manager from console ones.
|
||||
|
||||
TODO: it looks like wxSocketManager could be eliminated by providing
|
||||
methods for registering/unregistering sockets directly in
|
||||
wxEventLoop.
|
||||
*/
|
||||
|
||||
#ifndef _WX_PRIVATE_SOCKET_H_
|
||||
#define _WX_PRIVATE_SOCKET_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
#if wxUSE_SOCKETS
|
||||
|
||||
#include "wx/socket.h"
|
||||
#include "wx/private/sckaddr.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
Including sys/types.h under Cygwin results in the warnings about "fd_set
|
||||
having been defined in sys/types.h" when winsock.h is included later and
|
||||
doesn't seem to be necessary anyhow. It's not needed under Mac either.
|
||||
*/
|
||||
#if !defined(__WXMAC__) && !defined(__WXMSW__)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
// include the header defining timeval: under Windows this struct is used only
|
||||
// with sockets so we need to include winsock.h which we do via windows.h
|
||||
#ifdef __WINDOWS__
|
||||
#include "wx/msw/wrapwin.h"
|
||||
#else
|
||||
#include <sys/time.h> // for timeval
|
||||
#endif
|
||||
|
||||
// 64 bit Cygwin can't use the standard struct timeval because it has long
|
||||
// fields, which are supposed to be 32 bits in Win64 API, but long is 64 bits
|
||||
// in 64 bit Cygwin, so we need to use its special __ms_timeval instead.
|
||||
#if defined(__CYGWIN__) && defined(__LP64__) && defined(__WINDOWS__)
|
||||
typedef __ms_timeval wxTimeVal_t;
|
||||
#else
|
||||
typedef timeval wxTimeVal_t;
|
||||
#endif
|
||||
|
||||
// these definitions are for MSW when we don't use configure, otherwise these
|
||||
// symbols are defined by configure
|
||||
#ifndef WX_SOCKLEN_T
|
||||
#define WX_SOCKLEN_T int
|
||||
#endif
|
||||
|
||||
#ifndef SOCKOPTLEN_T
|
||||
#define SOCKOPTLEN_T int
|
||||
#endif
|
||||
|
||||
// define some symbols which winsock.h defines but traditional BSD headers
|
||||
// don't
|
||||
#ifndef INVALID_SOCKET
|
||||
#define INVALID_SOCKET (-1)
|
||||
#endif
|
||||
|
||||
#ifndef SOCKET_ERROR
|
||||
#define SOCKET_ERROR (-1)
|
||||
#endif
|
||||
|
||||
typedef int wxSocketEventFlags;
|
||||
|
||||
class wxSocketImpl;
|
||||
|
||||
/*
|
||||
Class providing hooks abstracting the differences between console and GUI
|
||||
applications for socket code.
|
||||
|
||||
We also have different implementations of this class for different platforms
|
||||
allowing us to keep more things in the common code but the main reason for
|
||||
its existence is that we want the same socket code work differently
|
||||
depending on whether it's used from a console or a GUI program. This is
|
||||
achieved by implementing the virtual methods of this class differently in
|
||||
the objects returned by wxConsoleAppTraits::GetSocketManager() and the same
|
||||
method in wxGUIAppTraits.
|
||||
*/
|
||||
class wxSocketManager
|
||||
{
|
||||
public:
|
||||
// set the manager to use, we don't take ownership of it
|
||||
//
|
||||
// this should be called before creating the first wxSocket object,
|
||||
// otherwise the manager returned by wxAppTraits::GetSocketManager() will
|
||||
// be used
|
||||
static void Set(wxSocketManager *manager);
|
||||
|
||||
// return the manager to use
|
||||
//
|
||||
// this initializes the manager at first use
|
||||
static wxSocketManager *Get()
|
||||
{
|
||||
if ( !ms_manager )
|
||||
Init();
|
||||
|
||||
return ms_manager;
|
||||
}
|
||||
|
||||
// called before the first wxSocket is created and should do the
|
||||
// initializations needed in order to use the network
|
||||
//
|
||||
// return true if initialized successfully; if this returns false sockets
|
||||
// can't be used at all
|
||||
virtual bool OnInit() = 0;
|
||||
|
||||
// undo the initializations of OnInit()
|
||||
virtual void OnExit() = 0;
|
||||
|
||||
|
||||
// create the socket implementation object matching this manager
|
||||
virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket) = 0;
|
||||
|
||||
// these functions enable or disable monitoring of the given socket for the
|
||||
// specified events inside the currently running event loop (but notice
|
||||
// that both BSD and Winsock implementations actually use socket->m_server
|
||||
// value to determine what exactly should be monitored so it needs to be
|
||||
// set before calling these functions)
|
||||
//
|
||||
// the default event value is used just for the convenience of wxMSW
|
||||
// implementation which doesn't use this parameter anyhow, it doesn't make
|
||||
// sense to pass wxSOCKET_LOST for the Unix implementation which does use
|
||||
// this parameter
|
||||
virtual void Install_Callback(wxSocketImpl *socket,
|
||||
wxSocketNotify event = wxSOCKET_LOST) = 0;
|
||||
virtual void Uninstall_Callback(wxSocketImpl *socket,
|
||||
wxSocketNotify event = wxSOCKET_LOST) = 0;
|
||||
|
||||
virtual ~wxSocketManager() = default;
|
||||
|
||||
private:
|
||||
// get the manager to use if we don't have it yet
|
||||
static void Init();
|
||||
|
||||
static wxSocketManager *ms_manager;
|
||||
};
|
||||
|
||||
/*
|
||||
Base class for all socket implementations providing functionality common to
|
||||
BSD and Winsock sockets.
|
||||
|
||||
Objects of this class are not created directly but only via the factory
|
||||
function wxSocketManager::CreateSocket().
|
||||
*/
|
||||
class wxSocketImpl
|
||||
{
|
||||
public:
|
||||
virtual ~wxSocketImpl();
|
||||
|
||||
// set various socket properties: all of those can only be called before
|
||||
// creating the socket
|
||||
void SetTimeout(unsigned long millisec);
|
||||
void SetReusable() { m_reusable = true; }
|
||||
void SetBroadcast() { m_broadcast = true; }
|
||||
void DontDoBind() { m_dobind = false; }
|
||||
void SetInitialSocketBuffers(int recv, int send)
|
||||
{
|
||||
m_initialRecvBufferSize = recv;
|
||||
m_initialSendBufferSize = send;
|
||||
}
|
||||
|
||||
wxSocketError SetLocal(const wxSockAddressImpl& address);
|
||||
wxSocketError SetPeer(const wxSockAddressImpl& address);
|
||||
|
||||
// accessors
|
||||
// ---------
|
||||
|
||||
bool IsServer() const { return m_server; }
|
||||
|
||||
const wxSockAddressImpl& GetLocal(); // non const as may update m_local
|
||||
const wxSockAddressImpl& GetPeer() const { return m_peer; }
|
||||
|
||||
wxSocketError GetError() const { return m_error; }
|
||||
bool IsOk() const { return m_error == wxSOCKET_NOERROR; }
|
||||
|
||||
// creating/closing the socket
|
||||
// --------------------------
|
||||
|
||||
// notice that SetLocal() must be called before creating the socket using
|
||||
// any of the functions below
|
||||
//
|
||||
// all of Create() functions return wxSOCKET_NOERROR if the operation
|
||||
// completed successfully or one of:
|
||||
// wxSOCKET_INVSOCK - the socket is in use.
|
||||
// wxSOCKET_INVADDR - the local (server) or peer (client) address has not
|
||||
// been set.
|
||||
// wxSOCKET_IOERR - any other error.
|
||||
|
||||
// create a socket listening on the local address specified by SetLocal()
|
||||
// (notice that DontDoBind() is ignored by this function)
|
||||
wxSocketError CreateServer();
|
||||
|
||||
// create a socket connected to the peer address specified by SetPeer()
|
||||
// (notice that DontDoBind() is ignored by this function)
|
||||
//
|
||||
// this function may return wxSOCKET_WOULDBLOCK in addition to the return
|
||||
// values listed above if wait is false
|
||||
wxSocketError CreateClient(bool wait);
|
||||
|
||||
// create (and bind unless DontDoBind() had been called) an UDP socket
|
||||
// associated with the given local address
|
||||
wxSocketError CreateUDP();
|
||||
|
||||
// may be called whether the socket was created or not, calls DoClose() if
|
||||
// it was indeed created
|
||||
void Close();
|
||||
|
||||
// shuts down the writing end of the socket and closes it, this is a more
|
||||
// graceful way to close
|
||||
//
|
||||
// does nothing if the socket wasn't created
|
||||
void Shutdown();
|
||||
|
||||
|
||||
// IO operations
|
||||
// -------------
|
||||
|
||||
// basic IO, work for both TCP and UDP sockets
|
||||
//
|
||||
// return the number of bytes read/written (possibly 0) or -1 on error
|
||||
int Read(void *buffer, int size);
|
||||
int Write(const void *buffer, int size);
|
||||
|
||||
// basically a wrapper for select(): returns the condition of the socket,
|
||||
// blocking for not longer than timeout if it is specified (otherwise just
|
||||
// poll without blocking at all)
|
||||
//
|
||||
// flags defines what kind of conditions we're interested in, the return
|
||||
// value is composed of a (possibly empty) subset of the bits set in flags
|
||||
wxSocketEventFlags Select(wxSocketEventFlags flags,
|
||||
wxTimeVal_t *timeout = nullptr);
|
||||
|
||||
// convenient wrapper calling Select() with our default timeout
|
||||
wxSocketEventFlags SelectWithTimeout(wxSocketEventFlags flags)
|
||||
{
|
||||
return Select(flags, &m_timeout);
|
||||
}
|
||||
|
||||
// just a wrapper for accept(): it is called to create a new wxSocketImpl
|
||||
// corresponding to a new server connection represented by the given
|
||||
// wxSocketBase, returns nullptr on error (including immediately if there are
|
||||
// no pending connections as our sockets are non-blocking)
|
||||
wxSocketImpl *Accept(wxSocketBase& wxsocket);
|
||||
|
||||
|
||||
// notifications
|
||||
// -------------
|
||||
|
||||
// Update the socket depending on the presence or absence of wxSOCKET_BLOCK
|
||||
// in GetSocketFlags(): if it's present, make the socket blocking and
|
||||
// ensure that we don't get any asynchronous event for it, otherwise put
|
||||
// it into non-blocking mode and enable monitoring it in the event loop.
|
||||
virtual void UpdateBlockingState() = 0;
|
||||
|
||||
// notify m_wxsocket about the given socket event by calling its (inaptly
|
||||
// named) OnRequest() method
|
||||
void NotifyOnStateChange(wxSocketNotify event);
|
||||
|
||||
// called after reading/writing the data from/to the socket and should
|
||||
// enable back the wxSOCKET_INPUT/OUTPUT_FLAG notifications if they were
|
||||
// turned off when this data was first detected
|
||||
virtual void ReenableEvents(wxSocketEventFlags flags) = 0;
|
||||
|
||||
// TODO: make these fields protected and provide accessors for those of
|
||||
// them that wxSocketBase really needs
|
||||
//protected:
|
||||
wxSOCKET_T m_fd;
|
||||
|
||||
int m_initialRecvBufferSize;
|
||||
int m_initialSendBufferSize;
|
||||
|
||||
wxSockAddressImpl m_local,
|
||||
m_peer;
|
||||
wxSocketError m_error;
|
||||
|
||||
bool m_stream;
|
||||
bool m_establishing;
|
||||
bool m_reusable;
|
||||
bool m_broadcast;
|
||||
bool m_dobind;
|
||||
|
||||
wxTimeVal_t m_timeout;
|
||||
|
||||
protected:
|
||||
wxSocketImpl(wxSocketBase& wxsocket);
|
||||
|
||||
// get the associated socket flags
|
||||
wxSocketFlags GetSocketFlags() const { return m_wxsocket->GetFlags(); }
|
||||
|
||||
// set m_error to the outcome of the last operation and return it
|
||||
wxSocketError UpdateLastError() { m_error = GetLastError(); return m_error; }
|
||||
|
||||
// true if we're a listening stream socket
|
||||
bool m_server;
|
||||
|
||||
private:
|
||||
// get the error code corresponding to the last operation
|
||||
//
|
||||
// this is private because it's only used by UpdateLastError()
|
||||
virtual wxSocketError GetLastError() const = 0;
|
||||
|
||||
// called by Close() if we have a valid m_fd
|
||||
virtual void DoClose() = 0;
|
||||
|
||||
// check that the socket wasn't created yet and that the given address
|
||||
// (either m_local or m_peer depending on the socket kind) is valid and
|
||||
// set m_error and return false if this is not the case
|
||||
bool PreCreateCheck(const wxSockAddressImpl& addr);
|
||||
|
||||
// set the given socket option: this just wraps setsockopt(SOL_SOCKET)
|
||||
int SetSocketOption(int optname, int optval)
|
||||
{
|
||||
// although modern Unix systems use "const void *" for the 4th
|
||||
// parameter here, old systems and Winsock still use "const char *"
|
||||
return setsockopt(m_fd, SOL_SOCKET, optname,
|
||||
reinterpret_cast<const char *>(&optval),
|
||||
sizeof(optval));
|
||||
}
|
||||
|
||||
// set the given socket option to true value: this is an even simpler
|
||||
// wrapper for setsockopt(SOL_SOCKET) for boolean options
|
||||
int EnableSocketOption(int optname)
|
||||
{
|
||||
return SetSocketOption(optname, 1);
|
||||
}
|
||||
|
||||
// apply the options to the (just created) socket and register it with the
|
||||
// event loop by calling UpdateBlockingState()
|
||||
void PostCreation();
|
||||
|
||||
// update local address after binding/connecting
|
||||
wxSocketError UpdateLocalAddress();
|
||||
|
||||
// functions used to implement Read/Write()
|
||||
int RecvStream(void *buffer, int size);
|
||||
int RecvDgram(void *buffer, int size);
|
||||
int SendStream(const void *buffer, int size);
|
||||
int SendDgram(const void *buffer, int size);
|
||||
|
||||
|
||||
// set in ctor and never changed except that it's reset to nullptr when the
|
||||
// socket is shut down
|
||||
wxSocketBase *m_wxsocket;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxSocketImpl);
|
||||
};
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#include "wx/msw/private/sockmsw.h"
|
||||
#else
|
||||
#include "wx/unix/private/sockunix.h"
|
||||
#endif
|
||||
|
||||
#endif /* wxUSE_SOCKETS */
|
||||
|
||||
#endif /* _WX_PRIVATE_SOCKET_H_ */
|
||||
Reference in New Issue
Block a user