diff --git a/include/wx/msw/gsockmsw.h b/include/wx/msw/gsockmsw.h index a32589d602..f7970f6ffd 100644 --- a/include/wx/msw/gsockmsw.h +++ b/include/wx/msw/gsockmsw.h @@ -80,6 +80,13 @@ public: void *optval, int *optlen); GSocketError SetSockOpt(int level, int optname, const void *optval, int optlen); + + void SetInitialSocketBuffers(int recv, int send) + { + m_initialRecvBufferSize = recv; + m_initialSendBufferSize = send; + } + protected: GSocketError Input_Timeout(); GSocketError Output_Timeout(); @@ -89,6 +96,8 @@ protected: int Send_Stream(const char *buffer, int size); int Send_Dgram(const char *buffer, int size); bool m_ok; + int m_initialRecvBufferSize; + int m_initialSendBufferSize; /* TODO: Make these protected */ public: diff --git a/include/wx/socket.h b/include/wx/socket.h index ea55c060db..5e9e687b3e 100644 --- a/include/wx/socket.h +++ b/include/wx/socket.h @@ -263,8 +263,21 @@ public: bool WaitOnConnect(long seconds = -1, long milliseconds = 0); + // Sets initial socket buffer sizes using the SO_SNDBUF and SO_RCVBUF options + // before calling connect (either one can be -1 to leave it unchanged) + void SetInitialSocketBuffers(int recv, int send) + { + m_initialRecvBufferSize = recv; + m_initialSendBufferSize = send; + } + private: - virtual bool DoConnect(wxSockAddress& addr, wxSockAddress* local, bool wait = true); + virtual bool + DoConnect(wxSockAddress& addr, wxSockAddress* local, bool wait = true); + + // buffer sizes, -1 if unset and defaults should be used + int m_initialRecvBufferSize; + int m_initialSendBufferSize; DECLARE_NO_COPY_CLASS(wxSocketClient) }; diff --git a/include/wx/unix/gsockunx.h b/include/wx/unix/gsockunx.h index a01f6013d2..c1a42f2b8c 100644 --- a/include/wx/unix/gsockunx.h +++ b/include/wx/unix/gsockunx.h @@ -72,6 +72,12 @@ public: const void *optval, int optlen); virtual void Detected_Read(); virtual void Detected_Write(); + void SetInitialSocketBuffers(int recv, int send) + { + m_initialRecvBufferSize = recv; + m_initialSendBufferSize = send; + } + protected: void Enable(GSocketEvent event); void Disable(GSocketEvent event); @@ -82,6 +88,8 @@ protected: int Send_Stream(const char *buffer, int size); int Send_Dgram(const char *buffer, int size); bool m_ok; + int m_initialRecvBufferSize; + int m_initialSendBufferSize; public: /* DFE: We can't protect these data member until the GUI code is updated */ /* protected: */ diff --git a/src/common/socket.cpp b/src/common/socket.cpp index e90a3b7cb5..203d79a063 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -1303,6 +1303,10 @@ bool wxSocketClient::DoConnect(wxSockAddress& addr_man, wxSockAddress* local, bo m_socket->SetLocal(la); } +#if defined(__WXMSW__) || defined(__WXGTK__) + m_socket->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize); +#endif + m_socket->SetPeer(addr_man.GetAddress()); err = m_socket->Connect(GSOCK_STREAMED); diff --git a/src/msw/gsocket.cpp b/src/msw/gsocket.cpp index 63da499669..393d15c29c 100644 --- a/src/msw/gsocket.cpp +++ b/src/msw/gsocket.cpp @@ -179,7 +179,9 @@ GSocket::GSocket() m_reusable = false; m_broadcast = false; m_dobind = true; - + m_initialRecvBufferSize = -1; + m_initialSendBufferSize = -1; + assert(gs_gui_functions); /* Per-socket GUI-specific initialization */ m_ok = gs_gui_functions->Init_Socket(this); @@ -630,6 +632,11 @@ GSocketError GSocket::Connect(GSocketStream stream) setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg)); } + if (m_initialRecvBufferSize >= 0) + setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&m_initialRecvBufferSize, sizeof(m_initialRecvBufferSize)); + if (m_initialSendBufferSize >= 0) + setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&m_initialSendBufferSize, sizeof(m_initialSendBufferSize)); + // If a local address has been set, then we need to bind to it before calling connect if (m_local && m_local->m_addr) { diff --git a/src/unix/gsocket.cpp b/src/unix/gsocket.cpp index bd71d70be5..0fbdcb3e35 100644 --- a/src/unix/gsocket.cpp +++ b/src/unix/gsocket.cpp @@ -541,6 +541,8 @@ GSocket::GSocket() m_timeout = 10*60*1000; /* 10 minutes * 60 sec * 1000 millisec */ m_establishing = false; + m_initialRecvBufferSize = -1; + m_initialSendBufferSize = -1; assert(gs_gui_functions); /* Per-socket GUI-specific initialization */ @@ -1019,6 +1021,11 @@ GSocketError GSocket::Connect(GSocketStream stream) #endif } + if (m_initialRecvBufferSize >= 0) + setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&m_initialRecvBufferSize, sizeof(m_initialRecvBufferSize)); + if (m_initialSendBufferSize >= 0) + setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&m_initialSendBufferSize, sizeof(m_initialSendBufferSize)); + // If a local address has been set, then we need to bind to it before calling connect if (m_local && m_local->m_addr) {