/////////////////////////////////////////////////////////////////////////////
// Name: wx/private/socket.h
-// Purpose: wxSocketImpl nd related declarations
+// Purpose: wxSocketImpl and related declarations
// Authors: Guilhem Lavaux, Vadim Zeitlin
// Created: April 1997
-// RCS-ID: $Id: socket.h 56994 2008-11-28 12:47:07Z VZ $
// Copyright: (c) 1997 Guilhem Lavaux
// (c) 2008 Vadim Zeitlin
// Licence: wxWindows licence
#if wxUSE_SOCKETS
#include "wx/socket.h"
+#include "wx/private/sckaddr.h"
#include <stddef.h>
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(__CYGWIN__) && !defined(__WXWINCE__)
+#if !defined(__WXMAC__) && !defined(__WXMSW__) && !defined(__WXWINCE__)
#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 __WXMSW__
+#ifdef __WINDOWS__
#include "wx/msw/wrapwin.h"
#else
#include <sys/time.h> // for timeval
// define some symbols which winsock.h defines but traditional BSD headers
// don't
-#ifndef SOCKET
- #define SOCKET int
-#endif
-
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (-1)
#endif
#define SOCKET_ERROR (-1)
#endif
-#if wxUSE_IPV6
- typedef struct sockaddr_storage wxSockAddr;
-#else
- typedef struct sockaddr wxSockAddr;
-#endif
-
-enum GAddressType
-{
- wxSOCKET_NOFAMILY = 0,
- wxSOCKET_INET,
- wxSOCKET_INET6,
- wxSOCKET_UNIX
-};
-
typedef int wxSocketEventFlags;
-struct GAddress;
class wxSocketImpl;
/*
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_MAX_EVENT) = 0;
+ wxSocketNotify event = wxSOCKET_LOST) = 0;
virtual void Uninstall_Callback(wxSocketImpl *socket,
- wxSocketNotify event = wxSOCKET_MAX_EVENT) = 0;
+ wxSocketNotify event = wxSOCKET_LOST) = 0;
virtual ~wxSocketManager() { }
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 its static
- Create() method which is implemented in port-specific code.
+ Objects of this class are not created directly but only via the factory
+ function wxSocketManager::CreateSocket().
*/
class wxSocketImpl
{
public:
- // static factory function: creates the low-level socket associated with
- // the given wxSocket (and inherits its attributes such as timeout)
- static wxSocketImpl *Create(wxSocketBase& wxsocket);
-
virtual ~wxSocketImpl();
// set various socket properties: all of those can only be called before
// creating the socket
void SetTimeout(unsigned long millisec);
- void SetNonBlocking(bool non_blocking) { m_non_blocking = non_blocking; }
void SetReusable() { m_reusable = true; }
void SetBroadcast() { m_broadcast = true; }
void DontDoBind() { m_dobind = false; }
m_initialSendBufferSize = send;
}
- wxSocketError SetLocal(GAddress *address);
- wxSocketError SetPeer(GAddress *address);
+ wxSocketError SetLocal(const wxSockAddressImpl& address);
+ wxSocketError SetPeer(const wxSockAddressImpl& address);
// accessors
// ---------
- GAddress *GetLocal();
- GAddress *GetPeer();
+ 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 DontDoBind() is ignored by this function)
//
// this function may return wxSOCKET_WOULDBLOCK in addition to the return
- // values listed above
- wxSocketError CreateClient();
+ // 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
// it was indeed created
void Close();
- virtual void Shutdown();
+ // 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
// -------------
- virtual int Read(char *buffer, int size) = 0;
- virtual int Write(const char *buffer, int size) = 0;
+ // 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);
- wxSocketEventFlags Select(wxSocketEventFlags flags);
+ // convenient wrapper calling Select() with our default timeout
+ wxSocketEventFlags SelectWithTimeout(wxSocketEventFlags flags)
+ {
+ return Select(flags, &m_timeout);
+ }
- virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket) = 0;
+ // 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
// named) OnRequest() method
void NotifyOnStateChange(wxSocketNotify event);
- // FIXME: this one probably isn't needed here at all
- virtual void Notify(bool WXUNUSED(notify)) { }
+ // 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;
+ wxSOCKET_T m_fd;
int m_initialRecvBufferSize;
int m_initialSendBufferSize;
- GAddress *m_local;
- GAddress *m_peer;
+ wxSockAddressImpl m_local,
+ m_peer;
wxSocketError m_error;
- bool m_non_blocking;
- bool m_server;
bool m_stream;
bool m_establishing;
bool m_reusable;
struct timeval m_timeout;
- wxSocketEventFlags m_detected;
-
protected:
wxSocketImpl(wxSocketBase& wxsocket);
-private:
- // handle the given connect() return value (which may be 0 or EWOULDBLOCK
- // or something else)
- virtual wxSocketError DoHandleConnect(int ret) = 0;
+ // 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;
// 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(GAddress *addr);
+ bool PreCreateCheck(const wxSockAddressImpl& addr);
// set the given socket option: this just wraps setsockopt(SOL_SOCKET)
int SetSocketOption(int optname, int optval)
// 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;
- DECLARE_NO_COPY_CLASS(wxSocketImpl)
+ wxDECLARE_NO_COPY_CLASS(wxSocketImpl);
};
-#if defined(__WXMSW__)
- #include "wx/msw/gsockmsw.h"
+#if defined(__WINDOWS__)
+ #include "wx/msw/private/sockmsw.h"
#else
#include "wx/unix/private/sockunix.h"
#endif
-
-/* GAddress */
-
-// TODO: make GAddress a real class instead of this mix of C and C++
-
-// Represents a socket endpoint, i.e. -- in spite of its name -- not an address
-// but an (address, port) pair
-struct GAddress
-{
- struct sockaddr *m_addr;
- size_t m_len;
-
- GAddressType m_family;
- int m_realfamily;
-
- wxSocketError m_error;
-};
-
-GAddress *GAddress_new();
-GAddress *GAddress_copy(GAddress *address);
-void GAddress_destroy(GAddress *address);
-
-void GAddress_SetFamily(GAddress *address, GAddressType type);
-GAddressType GAddress_GetFamily(GAddress *address);
-
-/* The use of any of the next functions will set the address family to
- * the specific one. For example if you use GAddress_INET_SetHostName,
- * address family will be implicitly set to AF_INET.
- */
-
-wxSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname);
-wxSocketError GAddress_INET_SetBroadcastAddress(GAddress *address);
-wxSocketError GAddress_INET_SetAnyAddress(GAddress *address);
-wxSocketError GAddress_INET_SetHostAddress(GAddress *address,
- unsigned long hostaddr);
-wxSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
- const char *protocol);
-wxSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port);
-
-wxSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
- size_t sbuf);
-unsigned long GAddress_INET_GetHostAddress(GAddress *address);
-unsigned short GAddress_INET_GetPort(GAddress *address);
-
-wxSocketError _GAddress_translate_from(GAddress *address,
- struct sockaddr *addr, int len);
-wxSocketError _GAddress_translate_to (GAddress *address,
- struct sockaddr **addr, int *len);
-wxSocketError _GAddress_Init_INET(GAddress *address);
-
-#if wxUSE_IPV6
-
-wxSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname);
-wxSocketError GAddress_INET6_SetAnyAddress(GAddress *address);
-wxSocketError GAddress_INET6_SetHostAddress(GAddress *address,
- struct in6_addr hostaddr);
-wxSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
- const char *protocol);
-wxSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port);
-
-wxSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname,
- size_t sbuf);
-wxSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr);
-unsigned short GAddress_INET6_GetPort(GAddress *address);
-
-#endif // wxUSE_IPV6
-
-// these functions are available under all platforms but only implemented under
-// Unix ones, elsewhere they just return wxSOCKET_INVADDR
-wxSocketError _GAddress_Init_UNIX(GAddress *address);
-wxSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
-wxSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
-
#endif /* wxUSE_SOCKETS */
#endif /* _WX_PRIVATE_SOCKET_H_ */