2 // This file is part of the aMule Project.
4 // Copyright (c) 2011-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2011-2011 Stu Redman ( admin@amule.org / http://www.amule.org )
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #ifndef __LIBSOCKET_H__
28 #define __LIBSOCKET_H__
30 #include "config.h" // Needed for ASIO_SOCKETS
32 class amuleIPV4Address
;
36 // Socket flags (unused in ASIO implementation, just provide the names)
39 MULE_SOCKET_NOWAIT_READ
,
40 MULE_SOCKET_NOWAIT_WRITE
,
42 MULE_SOCKET_WAITALL_READ
,
43 MULE_SOCKET_WAITALL_WRITE
,
46 MULE_SOCKET_REUSEADDR
,
47 MULE_SOCKET_BROADCAST
,
50 typedef int muleSocketFlags
;
52 // Socket events (used for proxy notification)
54 MULE_SOCKET_CONNECTION
,
61 // Abstraction class for library TCP socket
62 // Can be a wxSocket or an ASIO socket
70 friend class CAsioSocketImpl
;
71 friend class CAsioSocketServerImpl
;
73 CLibSocket(int flags
= 0);
74 virtual ~CLibSocket();
78 bool Connect(const amuleIPV4Address
& adr
, bool wait
);
79 bool IsConnected() const;
81 void SetLocal(const amuleIPV4Address
& local
);
82 uint32
Read(void * buffer
, uint32 nbytes
);
83 uint32
Write(const void * buffer
, uint32 nbytes
);
87 // Get last error, 0 == no error
88 int LastError() const;
93 bool WaitOnConnect(long, long) { return true; }
94 bool WaitForWrite(long, long) { return true; }
95 bool WaitForRead(long, long) { return true; }
99 // Check if socket is currently blocking for read or write
100 bool BlocksRead() const;
101 bool BlocksWrite() const;
103 // Show we're ready for another event
104 void EventProcessed();
107 const wxChar
* GetIP() const;
109 // True if Destroy() has been called for socket
110 bool IsDestroying() const;
112 // Get/set proxy state
113 bool GetProxyState() const;
114 void SetProxyState(bool state
, const amuleIPV4Address
* adr
= 0);
116 // Get peer address (better API than wx)
121 virtual void OnConnect(int) {}
122 virtual void OnSend(int) {}
123 virtual void OnReceive(int) {}
124 virtual void OnLost() {}
125 virtual void OnProxyEvent(int) {}
128 // Replace the internal socket
129 void LinkSocketImpl(class CAsioSocketImpl
*);
131 class CAsioSocketImpl
* m_aSocket
;
132 void LastCount(); // No. We don't have this. We return it directly with Read() and Write()
133 bool Error() const; // Only use LastError
140 class CLibSocketServer
143 CLibSocketServer(const amuleIPV4Address
& adr
, int flags
);
144 virtual ~CLibSocketServer();
145 // Accepts an incoming connection request, and creates a new CLibSocket object which represents the server-side of the connection.
146 CLibSocket
* Accept(bool wait
= true);
147 // Accept an incoming connection using the specified socket object.
148 bool AcceptWith(CLibSocket
& socket
, bool wait
);
150 virtual void OnAccept() {}
158 bool Notify(bool) { return true; }
162 // Do we have a socket available if AcceptWith() is called ?
163 bool SocketAvailable();
165 class CAsioSocketServerImpl
* m_aServer
;
174 friend class CAsioUDPSocketImpl
;
176 CLibUDPSocket(amuleIPV4Address
&address
, int flags
);
177 virtual ~CLibUDPSocket();
181 virtual uint32
RecvFrom(amuleIPV4Address
& addr
, void* buf
, uint32 nBytes
);
182 virtual uint32
SendTo(const amuleIPV4Address
& addr
, const void* buf
, uint32 nBytes
);
183 int LastError() const;
186 void SetClientData(class CMuleUDPSocket
*);
189 bool Notify(bool) { return true; }
191 // Check if socket is currently blocking for write
192 // Well - we apparently have block in wx. At least we handle it in MuleUDPSocket.
193 // But this makes no sense. We send a packet to an IP in background.
194 // Either this works after some time, or not. But there is no block.
195 bool BlocksWrite() const { return false; }
198 class CAsioUDPSocketImpl
* m_aSocket
;
199 void LastCount(); // block this
200 bool Error() const; // Only use LastError
214 static const int m_numberOfThreads
;
215 class CAsioServiceThread
* m_threads
;
219 #else /* ASIO_SOCKETS */
223 #include <wx/socket.h>
224 #include "NetworkFunctions.h" // Needed for StringIPtoUint32
226 typedef wxSocketFlags muleSocketFlags
;
229 #define MULE_SOCKET_NONE wxSOCKET_NONE
230 #define MULE_SOCKET_NOWAIT_READ wxSOCKET_NOWAIT_READ
231 #define MULE_SOCKET_NOWAIT_WRITE wxSOCKET_NOWAIT_WRITE
232 #define MULE_SOCKET_NOWAIT wxSOCKET_NOWAIT
233 #define MULE_SOCKET_WAITALL_READ wxSOCKET_WAITALL_READ
234 #define MULE_SOCKET_WAITALL_WRITE wxSOCKET_WAITALL_WRITE
235 #define MULE_SOCKET_WAITALL wxSOCKET_WAITALL
236 #define MULE_SOCKET_BLOCK wxSOCKET_BLOCK
237 #define MULE_SOCKET_REUSEADDR wxSOCKET_REUSEADDR
238 #define MULE_SOCKET_BROADCAST wxSOCKET_BROADCAST
239 #define MULE_SOCKET_NOBIND wxSOCKET_NOBIND
242 #define MULE_SOCKET_CONNECTION wxSOCKET_CONNECTION
243 #define MULE_SOCKET_INPUT wxSOCKET_INPUT
244 #define MULE_SOCKET_OUTPUT wxSOCKET_OUTPUT
245 #define MULE_SOCKET_LOST wxSOCKET_LOST
247 class CLibSocket
: public wxSocketClient
250 CLibSocket(wxSocketFlags flags
= 0) : wxSocketClient(flags
), m_isDestroying(false) {}
252 // not actually called
253 const wxChar
* GetIP() const { return wxEmptyString
; }
254 void EventProcessed() {}
255 bool GetProxyState() const { return false; }
257 virtual void OnConnect(int) {}
258 virtual void OnSend(int) {}
259 virtual void OnReceive(int) {}
260 virtual void OnLost() {}
261 virtual void OnProxyEvent(int) {}
263 // methods using amuleIPV4Address
264 bool Connect(amuleIPV4Address
& adr
, bool wait
); // Yes. adr is not const.
265 bool GetPeer(amuleIPV4Address
& adr
);
266 void SetLocal(amuleIPV4Address
& local
); // Same here.
268 // Get last error, 0 == no error
269 // BLOCK is also not an error!
270 int LastError() const
273 if (wxSocketClient::Error()) {
274 ret
= wxSocketClient::LastError();
275 if (ret
== wxSOCKET_WOULDBLOCK
) {
282 // Check if socket is currently blocking for read or write
283 bool BlocksRead() const
285 return wxSocketClient::Error() && wxSocketClient::LastError() == wxSOCKET_WOULDBLOCK
;
288 bool BlocksWrite() const { return BlocksRead(); } // no difference here
290 uint32
Read(void *buffer
, wxUint32 nbytes
)
292 wxSocketClient::Read(buffer
, nbytes
);
293 return wxSocketClient::LastCount();
296 uint32
Write(const void *buffer
, wxUint32 nbytes
)
298 wxSocketClient::Write(buffer
, nbytes
);
299 return wxSocketClient::LastCount();
304 if (!m_isDestroying
) {
305 m_isDestroying
= true;
308 Close(); // Destroy is suposed to call Close(), but.. it doesn't hurt.
309 wxSocketClient::Destroy();
313 bool IsDestroying() const { return m_isDestroying
; }
315 // Get peer address (better API than wx)
319 wxSocketClient::GetPeer(adr
);
320 return adr
.IPAddress();
323 uint32
GetPeerInt() { return StringIPtoUint32(GetPeer()); }
326 bool m_isDestroying
; // true if Destroy() was called
328 void LastCount(); // block this
329 bool Error() const; // Only use LastError
333 class CLibSocketServer
: public wxSocketServer
336 CLibSocketServer(const amuleIPV4Address
&address
, wxSocketFlags flags
);
338 CLibSocket
* Accept(bool wait
) { return static_cast<CLibSocket
*>(wxSocketServer::Accept(wait
)); }
340 bool SocketAvailable() { return true; }
342 virtual void OnAccept() {}
346 class CLibUDPSocket
: public wxDatagramSocket
349 CLibUDPSocket(amuleIPV4Address
&address
, wxSocketFlags flags
);
351 virtual uint32
RecvFrom(amuleIPV4Address
& addr
, void* buf
, uint32 nBytes
);
353 virtual uint32
SendTo(const amuleIPV4Address
& addr
, const void* buf
, uint32 nBytes
);
355 // Get last error, 0 == no error
356 int LastError() const
359 if (wxDatagramSocket::Error()) {
360 ret
= wxDatagramSocket::LastError();
361 if (ret
== wxSOCKET_WOULDBLOCK
) {
368 // Check if socket is currently blocking for write
369 // I wonder if this EVER returns true (see Asio)
370 bool BlocksWrite() const
372 return wxDatagramSocket::Error() && wxDatagramSocket::LastError() == wxSOCKET_WOULDBLOCK
;
376 void LastCount(); // block this
377 bool Error() const; // Only use LastError
381 #endif /* ASIO_SOCKETS */
383 #endif /* __LIBSOCKET_H__ */