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
37 #include <wx/thread.h>
39 class amuleIPV4Address
;
42 // Abstraction class for library TCP socket
43 // Can be a wxSocket or an ASIO socket
51 friend class CAsioSocketImpl
;
52 friend class CAsioSocketServerImpl
;
54 CLibSocket(int flags
= 0);
55 virtual ~CLibSocket();
59 bool Connect(const amuleIPV4Address
& adr
, bool wait
);
60 bool IsConnected() const;
62 void SetLocal(const amuleIPV4Address
& local
);
63 uint32
Read(void * buffer
, uint32 nbytes
);
64 uint32
Write(const void * buffer
, uint32 nbytes
);
68 // Not needed here, we always notify the same way
69 void SetNotify(int) {}
70 void SetEventHandler(wxEvtHandler
&, int) {}
72 // Get last error, 0 == no error
73 int LastError() const;
78 bool WaitOnConnect(long, long) { return true; }
79 bool WaitForWrite(long, long) { return true; }
80 bool WaitForRead(long, long) { return true; }
84 // Check if socket is currently blocking for read or write
85 bool BlocksRead() const;
86 bool BlocksWrite() const;
88 // Show we're ready for another event
89 void EventProcessed();
92 const wxChar
* GetIP() const;
94 // True if Destroy() has been called for socket
95 bool IsDestroying() const;
97 // Get/set proxy state
98 bool GetProxyState() const;
99 void SetProxyState(bool state
, const amuleIPV4Address
* adr
= 0);
101 // Get peer address (better API than wx)
106 virtual void OnConnect(int) {}
107 virtual void OnSend(int) {}
108 virtual void OnReceive(int) {}
109 virtual void OnLost() {}
110 virtual void OnProxyEvent(int) {}
113 // Replace the internal socket
114 void LinkSocketImpl(class CAsioSocketImpl
*);
116 class CAsioSocketImpl
* m_aSocket
;
117 void LastCount(); // No. We don't have this. We return it directly with Read() and Write()
118 bool Error() const; // Only use LastError
125 class CLibSocketServer
128 CLibSocketServer(const amuleIPV4Address
& adr
, int flags
);
129 virtual ~CLibSocketServer();
130 // Accepts an incoming connection request, and creates a new CLibSocket object which represents the server-side of the connection.
131 CLibSocket
* Accept(bool wait
= true);
132 // Accept an incoming connection using the specified socket object.
133 bool AcceptWith(CLibSocket
& socket
, bool wait
);
135 virtual void OnAccept() {}
143 void SetEventHandler(wxEvtHandler
& , int ) {}
144 void SetNotify(int) {}
145 bool Notify(bool) { return true; }
149 // Do we have a socket available if AcceptWith() is called ?
150 bool SocketAvailable();
152 class CAsioSocketServerImpl
* m_aServer
;
161 friend class CAsioUDPSocketImpl
;
163 CLibUDPSocket(amuleIPV4Address
&address
, int flags
);
164 virtual ~CLibUDPSocket();
168 virtual uint32
RecvFrom(amuleIPV4Address
& addr
, void* buf
, uint32 nBytes
);
169 virtual uint32
SendTo(const amuleIPV4Address
& addr
, const void* buf
, uint32 nBytes
);
170 int LastError() const;
173 void SetClientData(class CMuleUDPSocket
*);
176 void SetEventHandler(wxEvtHandler
&, int) {}
177 void SetNotify(int) {}
178 bool Notify(bool) { return true; }
180 // Check if socket is currently blocking for write
181 // Well - we apparently have block in wx. At least we handle it in MuleUDPSocket.
182 // But this makes no sense. We send a packet to an IP in background.
183 // Either this works after some time, or not. But there is no block.
184 bool BlocksWrite() const { return false; }
187 class CAsioUDPSocketImpl
* m_aSocket
;
188 void LastCount(); // block this
189 bool Error() const; // Only use LastError
203 static const int m_numberOfThreads
;
204 class CAsioServiceThread
* m_threads
;
208 #else /* ASIO_SOCKETS */
212 #include <wx/socket.h>
213 #include "amuleIPV4Address.h"
215 class CLibSocket
: public wxSocketClient
218 CLibSocket(wxSocketFlags flags
= 0) : wxSocketClient(flags
), m_isDestroying(false) {}
220 // not actually called
221 const wxChar
* GetIP() const { return wxEmptyString
; }
222 void EventProcessed() {}
223 bool GetProxyState() const { return false; }
225 virtual void OnConnect(int) {}
226 virtual void OnSend(int) {}
227 virtual void OnReceive(int) {}
228 virtual void OnLost() {}
229 virtual void OnProxyEvent(int) {}
231 // methods using amuleIPV4Address
232 bool Connect(amuleIPV4Address
& adr
, bool wait
); // Yes. adr is not const.
233 bool GetPeer(amuleIPV4Address
& adr
);
234 void SetLocal(amuleIPV4Address
& local
); // Same here.
236 // Get last error, 0 == no error
237 // BLOCK is also not an error!
238 int LastError() const
241 if (wxSocketClient::Error()) {
242 ret
= wxSocketClient::LastError();
243 if (ret
== wxSOCKET_WOULDBLOCK
) {
250 // Check if socket is currently blocking for read or write
251 bool BlocksRead() const
253 return wxSocketClient::Error() && wxSocketClient::LastError() == wxSOCKET_WOULDBLOCK
;
256 bool BlocksWrite() const { return BlocksRead(); } // no difference here
258 uint32
Read(void *buffer
, wxUint32 nbytes
)
260 wxSocketClient::Read(buffer
, nbytes
);
261 return wxSocketClient::LastCount();
264 uint32
Write(const void *buffer
, wxUint32 nbytes
)
266 wxSocketClient::Write(buffer
, nbytes
);
267 return wxSocketClient::LastCount();
272 if (!m_isDestroying
) {
273 m_isDestroying
= true;
276 Close(); // Destroy is suposed to call Close(), but.. it doesn't hurt.
277 wxSocketClient::Destroy();
281 bool IsDestroying() const { return m_isDestroying
; }
283 // Get peer address (better API than wx)
287 wxSocketClient::GetPeer(adr
);
288 return adr
.IPAddress();
291 uint32
GetPeerInt() { return StringIPtoUint32(GetPeer()); }
294 bool m_isDestroying
; // true if Destroy() was called
296 void LastCount(); // block this
297 bool Error() const; // Only use LastError
301 class CLibSocketServer
: public wxSocketServer
304 CLibSocketServer(const amuleIPV4Address
&address
, wxSocketFlags flags
);
306 CLibSocket
* Accept(bool wait
) { return static_cast<CLibSocket
*>(wxSocketServer::Accept(wait
)); }
308 bool SocketAvailable() { return true; }
310 virtual void OnAccept() {}
314 class CLibUDPSocket
: public wxDatagramSocket
317 CLibUDPSocket(amuleIPV4Address
&address
, wxSocketFlags flags
);
319 virtual uint32
RecvFrom(amuleIPV4Address
& addr
, void* buf
, uint32 nBytes
);
321 virtual uint32
SendTo(const amuleIPV4Address
& addr
, const void* buf
, uint32 nBytes
);
323 // Get last error, 0 == no error
324 int LastError() const
327 if (wxDatagramSocket::Error()) {
328 ret
= wxDatagramSocket::LastError();
329 if (ret
== wxSOCKET_WOULDBLOCK
) {
336 // Check if socket is currently blocking for write
337 // I wonder if this EVER returns true (see Asio)
338 bool BlocksWrite() const
340 return wxDatagramSocket::Error() && wxDatagramSocket::LastError() == wxSOCKET_WOULDBLOCK
;
344 void LastCount(); // block this
345 bool Error() const; // Only use LastError
356 #endif /* ASIO_SOCKETS */
358 #endif /* __LIBSOCKET_H__ */