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__
31 # include "config.h" // Needed for ASIO_SOCKETS
35 class amuleIPV4Address
;
39 // Socket flags (unused in ASIO implementation, just provide the names)
42 MULE_SOCKET_NOWAIT_READ
,
43 MULE_SOCKET_NOWAIT_WRITE
,
45 MULE_SOCKET_WAITALL_READ
,
46 MULE_SOCKET_WAITALL_WRITE
,
49 MULE_SOCKET_REUSEADDR
,
50 MULE_SOCKET_BROADCAST
,
53 typedef int muleSocketFlags
;
55 // Socket events (used for proxy notification)
57 MULE_SOCKET_CONNECTION
,
64 // Abstraction class for library TCP socket
65 // Can be a wxSocket or an ASIO socket
73 friend class CAsioSocketImpl
;
74 friend class CAsioSocketServerImpl
;
76 CLibSocket(int flags
= 0);
77 virtual ~CLibSocket();
81 bool Connect(const amuleIPV4Address
& adr
, bool wait
);
82 bool IsConnected() const;
84 void SetLocal(const amuleIPV4Address
& local
);
85 uint32
Read(void * buffer
, uint32 nbytes
);
86 uint32
Write(const void * buffer
, uint32 nbytes
);
90 // Get last error, 0 == no error
91 int LastError() const;
96 bool WaitOnConnect(long, long) { return true; }
97 bool WaitForWrite(long, long) { return true; }
98 bool WaitForRead(long, long) { return true; }
102 // Check if socket is currently blocking for read or write
103 bool BlocksRead() const;
104 bool BlocksWrite() const;
106 // Show we're ready for another event
107 void EventProcessed();
110 const wxChar
* GetIP() const;
112 // True if Destroy() has been called for socket
113 bool IsDestroying() const;
115 // Get/set proxy state
116 bool GetProxyState() const;
117 void SetProxyState(bool state
, const amuleIPV4Address
* adr
= 0);
119 // Get peer address (better API than wx)
124 virtual void OnConnect(int) {}
125 virtual void OnSend(int) {}
126 virtual void OnReceive(int) {}
127 virtual void OnLost() {}
128 virtual void OnProxyEvent(int) {}
131 // Replace the internal socket
132 void LinkSocketImpl(class CAsioSocketImpl
*);
134 class CAsioSocketImpl
* m_aSocket
;
135 void LastCount(); // No. We don't have this. We return it directly with Read() and Write()
136 bool Error() const; // Only use LastError
143 class CLibSocketServer
146 CLibSocketServer(const amuleIPV4Address
& adr
, int flags
);
147 virtual ~CLibSocketServer();
148 // Accepts an incoming connection request, and creates a new CLibSocket object which represents the server-side of the connection.
149 CLibSocket
* Accept(bool wait
= true);
150 // Accept an incoming connection using the specified socket object.
151 bool AcceptWith(CLibSocket
& socket
, bool wait
);
153 virtual void OnAccept() {}
161 bool Notify(bool) { return true; }
165 // Do we have a socket available if AcceptWith() is called ?
166 bool SocketAvailable();
168 class CAsioSocketServerImpl
* m_aServer
;
177 friend class CAsioUDPSocketImpl
;
179 CLibUDPSocket(amuleIPV4Address
&address
, int flags
);
180 virtual ~CLibUDPSocket();
184 virtual uint32
RecvFrom(amuleIPV4Address
& addr
, void* buf
, uint32 nBytes
);
185 virtual uint32
SendTo(const amuleIPV4Address
& addr
, const void* buf
, uint32 nBytes
);
186 int LastError() const;
189 void SetClientData(class CMuleUDPSocket
*);
192 bool Notify(bool) { return true; }
194 // Check if socket is currently blocking for write
195 // Well - we apparently have block in wx. At least we handle it in MuleUDPSocket.
196 // But this makes no sense. We send a packet to an IP in background.
197 // Either this works after some time, or not. But there is no block.
198 bool BlocksWrite() const { return false; }
201 class CAsioUDPSocketImpl
* m_aSocket
;
202 void LastCount(); // block this
203 bool Error() const; // Only use LastError
217 static const int m_numberOfThreads
;
218 class CAsioServiceThread
* m_threads
;
222 #else /* ASIO_SOCKETS */
226 #include <wx/socket.h>
227 #include "NetworkFunctions.h" // Needed for StringIPtoUint32
229 typedef wxSocketFlags muleSocketFlags
;
232 #define MULE_SOCKET_NONE wxSOCKET_NONE
233 #define MULE_SOCKET_NOWAIT_READ wxSOCKET_NOWAIT_READ
234 #define MULE_SOCKET_NOWAIT_WRITE wxSOCKET_NOWAIT_WRITE
235 #define MULE_SOCKET_NOWAIT wxSOCKET_NOWAIT
236 #define MULE_SOCKET_WAITALL_READ wxSOCKET_WAITALL_READ
237 #define MULE_SOCKET_WAITALL_WRITE wxSOCKET_WAITALL_WRITE
238 #define MULE_SOCKET_WAITALL wxSOCKET_WAITALL
239 #define MULE_SOCKET_BLOCK wxSOCKET_BLOCK
240 #define MULE_SOCKET_REUSEADDR wxSOCKET_REUSEADDR
241 #define MULE_SOCKET_BROADCAST wxSOCKET_BROADCAST
242 #define MULE_SOCKET_NOBIND wxSOCKET_NOBIND
245 #define MULE_SOCKET_CONNECTION wxSOCKET_CONNECTION
246 #define MULE_SOCKET_INPUT wxSOCKET_INPUT
247 #define MULE_SOCKET_OUTPUT wxSOCKET_OUTPUT
248 #define MULE_SOCKET_LOST wxSOCKET_LOST
250 class CLibSocket
: public wxSocketClient
253 CLibSocket(wxSocketFlags flags
= 0) : wxSocketClient(flags
), m_isDestroying(false) {}
255 // not actually called
256 const wxChar
* GetIP() const { return wxEmptyString
; }
257 void EventProcessed() {}
258 bool GetProxyState() const { return false; }
260 virtual void OnConnect(int) {}
261 virtual void OnSend(int) {}
262 virtual void OnReceive(int) {}
263 virtual void OnLost() {}
264 virtual void OnProxyEvent(int) {}
266 // methods using amuleIPV4Address
267 bool Connect(amuleIPV4Address
& adr
, bool wait
); // Yes. adr is not const.
268 bool GetPeer(amuleIPV4Address
& adr
);
269 void SetLocal(amuleIPV4Address
& local
); // Same here.
271 // Get last error, 0 == no error
272 // BLOCK is also not an error!
273 int LastError() const
276 if (wxSocketClient::Error()) {
277 ret
= wxSocketClient::LastError();
278 if (ret
== wxSOCKET_WOULDBLOCK
) {
285 // Check if socket is currently blocking for read or write
286 bool BlocksRead() const
288 return wxSocketClient::Error() && wxSocketClient::LastError() == wxSOCKET_WOULDBLOCK
;
291 bool BlocksWrite() const { return BlocksRead(); } // no difference here
293 uint32
Read(void *buffer
, wxUint32 nbytes
)
295 wxSocketClient::Read(buffer
, nbytes
);
296 return wxSocketClient::LastCount();
299 uint32
Write(const void *buffer
, wxUint32 nbytes
)
301 wxSocketClient::Write(buffer
, nbytes
);
302 return wxSocketClient::LastCount();
307 if (!m_isDestroying
) {
308 m_isDestroying
= true;
311 Close(); // Destroy is suposed to call Close(), but.. it doesn't hurt.
312 wxSocketClient::Destroy();
316 bool IsDestroying() const { return m_isDestroying
; }
318 // Get peer address (better API than wx)
322 wxSocketClient::GetPeer(adr
);
323 return adr
.IPAddress();
326 uint32
GetPeerInt() { return StringIPtoUint32(GetPeer()); }
329 bool m_isDestroying
; // true if Destroy() was called
331 void LastCount(); // block this
332 bool Error() const; // Only use LastError
336 class CLibSocketServer
: public wxSocketServer
339 CLibSocketServer(const amuleIPV4Address
&address
, wxSocketFlags flags
);
341 CLibSocket
* Accept(bool wait
) { return static_cast<CLibSocket
*>(wxSocketServer::Accept(wait
)); }
343 bool SocketAvailable() { return true; }
345 virtual void OnAccept() {}
349 class CLibUDPSocket
: public wxDatagramSocket
352 CLibUDPSocket(amuleIPV4Address
&address
, wxSocketFlags flags
);
354 virtual uint32
RecvFrom(amuleIPV4Address
& addr
, void* buf
, uint32 nBytes
);
356 virtual uint32
SendTo(const amuleIPV4Address
& addr
, const void* buf
, uint32 nBytes
);
358 // Get last error, 0 == no error
359 int LastError() const
362 if (wxDatagramSocket::Error()) {
363 ret
= wxDatagramSocket::LastError();
364 if (ret
== wxSOCKET_WOULDBLOCK
) {
371 // Check if socket is currently blocking for write
372 // I wonder if this EVER returns true (see Asio)
373 bool BlocksWrite() const
375 return wxDatagramSocket::Error() && wxDatagramSocket::LastError() == wxSOCKET_WOULDBLOCK
;
379 void LastCount(); // block this
380 bool Error() const; // Only use LastError
384 #endif /* ASIO_SOCKETS */
386 #endif /* __LIBSOCKET_H__ */