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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#pragma once
#include "StarHostAddress.hpp"
#include "StarThread.hpp"
namespace Star {
// Thrown when some call on a socket failed because the socket is *either*
// closed or shutdown, for other errors sockets will throw NetworkException
STAR_EXCEPTION(SocketClosedException, NetworkException);
STAR_STRUCT(SocketImpl);
STAR_CLASS(Socket);
enum class SocketMode {
Closed,
Shutdown,
Bound,
Connected
};
struct SocketPollQueryEntry {
// Query whether the tcp socket is readable
bool readable;
// Query whether the tcp socket is writable
bool writable;
};
struct SocketPollResultEntry {
// The tcp socket can be read without blocking
bool readable;
// The tcp socket can be written without blocking
bool writable;
// The tcp socket has had an error condition, or it has been closed.
bool exception;
};
typedef Map<SocketPtr, SocketPollQueryEntry> SocketPollQuery;
typedef Map<SocketPtr, SocketPollResultEntry> SocketPollResult;
class Socket {
public:
// Waits for sockets that are readable, writiable, or have pending error
// conditions within the given timeout. Returns result if any sockets are
// ready for I/O or have had error events occur on them within the timeout,
// nothing otherwise. If socket hangup occurs during this call, this will
// automatically shut down the socket.
static Maybe<SocketPollResult> poll(SocketPollQuery const& query, unsigned timeout);
~Socket();
void bind(HostAddressWithPort const& address);
void listen(int backlog);
// Sockets default to blocking mode
void setNonBlocking(bool nonBlocking);
// Sockets default to 60 second timeout
void setTimeout(unsigned millis);
NetworkMode networkMode() const;
SocketMode socketMode() const;
// Is the socketMode either Bound or Connected?
bool isActive() const;
// Is the socketMode not closed?
bool isOpen() const;
// Shuts down the underlying socket only.
void shutdown();
// Shuts down and closes the underlying socket.
void close();
protected:
enum class SocketType {
Tcp,
Udp
};
Socket(SocketType type, NetworkMode networkMode);
Socket(NetworkMode networkMode, SocketImplPtr impl, SocketMode socketMode);
void checkOpen(char const* methodName) const;
void doShutdown();
void doClose();
mutable ReadersWriterMutex m_mutex;
NetworkMode m_networkMode;
SocketImplPtr m_impl;
atomic<SocketMode> m_socketMode;
HostAddressWithPort m_localAddress;
};
}
|