1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#pragma once
#ifdef _WIN32
#ifndef _MSC_VER
#include <windows.h>
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <netdb.h>
#endif
#include <Handle.h>
#include <Selectable.h>
#include <TaskMan.h>
#include <Task.h>
#include <StacklessTask.h>
#include <Printer.h>
namespace Balau {
struct DNSRequest;
class Socket : public Selectable {
public:
Socket() throw (GeneralException);
virtual ssize_t read(void * buf, size_t count) throw (GeneralException);
virtual ssize_t write(const void * buf, size_t count) throw (GeneralException);
virtual void close() throw (GeneralException);
virtual bool canRead();
virtual bool canWrite();
virtual const char * getName();
bool setLocal(const char * hostname = NULL, int port = 0);
bool connect(const char * hostname, int port);
IO<Socket> accept() throw (GeneralException);
bool listen();
bool resolved();
private:
Socket(int fd);
virtual ssize_t recv(int sockfd, void *buf, size_t len, int flags);
virtual ssize_t send(int sockfd, const void *buf, size_t len, int flags);
String m_name;
bool m_connected = false;
bool m_connecting = false;
bool m_listening = false;
sockaddr_in6 m_localAddr, m_remoteAddr;
DNSRequest * m_req = NULL;
};
class ListenerBase : public StacklessTask {
public:
virtual void Do();
void stop();
virtual const char * getName() const;
protected:
ListenerBase(int port, const char * local, void * opaque);
virtual void factory(IO<Socket> & io, void * opaque) = 0;
virtual void setName() = 0;
String m_name;
IO<Socket> m_listener;
private:
Events::Async m_evt;
volatile bool m_stop;
String m_local;
int m_port = 0;
void * m_opaque = NULL;
};
template<class Worker>
class Listener : public ListenerBase {
public:
Listener(int port, const char * local = "", void * opaque = NULL) : ListenerBase(port, local, opaque) { }
protected:
virtual void factory(IO<Socket> & io, void * opaque) { TaskMan::registerTask(new Worker(io, opaque)); }
virtual void setName() { m_name = String(ClassName(this).c_str()) + " - " + m_listener->getName(); }
};
};
|