Test for __WXMSW__ instead of __CYGWIN__ to not affect building non-MSW ports such as wxGTK under Cygwin. See #14382. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71799 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			379 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			379 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        wx/private/socket.h
 | 
						|
// Purpose:     wxSocketImpl and related declarations
 | 
						|
// Authors:     Guilhem Lavaux, Vadim Zeitlin
 | 
						|
// Created:     April 1997
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// 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 neither.
 | 
						|
 */
 | 
						|
#if !defined(__WXMAC__) && !defined(__WXMSW__) && !defined(__WXWINCE__)
 | 
						|
#include <sys/types.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef __WXWINCE__
 | 
						|
#include <stdlib.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
 | 
						|
 | 
						|
// 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 __WINDOWS__
 | 
						|
    #define SOCKET int
 | 
						|
#endif
 | 
						|
 | 
						|
#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() { }
 | 
						|
 | 
						|
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; }
 | 
						|
 | 
						|
    // get the error code corresponding to the last operation
 | 
						|
    virtual wxSocketError GetLastError() const = 0;
 | 
						|
 | 
						|
 | 
						|
    // 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,
 | 
						|
                              const timeval *timeout = NULL);
 | 
						|
 | 
						|
    // 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 NULL on error (including immediately if there are
 | 
						|
    // no pending connections as our sockets are non-blocking)
 | 
						|
    wxSocketImpl *Accept(wxSocketBase& wxsocket);
 | 
						|
 | 
						|
 | 
						|
    // notifications
 | 
						|
    // -------------
 | 
						|
 | 
						|
    // 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:
 | 
						|
    SOCKET 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;
 | 
						|
 | 
						|
    struct timeval m_timeout;
 | 
						|
 | 
						|
protected:
 | 
						|
    wxSocketImpl(wxSocketBase& wxsocket);
 | 
						|
 | 
						|
    // true if we're a listening stream socket
 | 
						|
    bool m_server;
 | 
						|
 | 
						|
private:
 | 
						|
    // called by Close() if we have a valid m_fd
 | 
						|
    virtual void DoClose() = 0;
 | 
						|
 | 
						|
    // put this socket into non-blocking mode and enable monitoring this socket
 | 
						|
    // as part of the event loop
 | 
						|
    virtual void UnblockAndRegisterWithEventLoop() = 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 UnblockAndRegisterWithEventLoop()
 | 
						|
    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 NULL 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_ */
 |