-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathConnection.h
More file actions
222 lines (185 loc) · 4.06 KB
/
Connection.h
File metadata and controls
222 lines (185 loc) · 4.06 KB
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#ifndef CONNECTION_H
#define CONNECTION_H
#include <stack>
#include "BasicLib.h"
#include "SocketLibTypes.h"
#include "ConnectionManager.h"
#include "SocketLibSocket.h"
namespace SocketLib
{
const static int BUFFERSIZE = 1024;
const static int TIMECHUNK = 16;
template<class protocol>
class Connection : public DataSocket
{
public:
Connection();
Connection(DataSocket& p_socket);
protected:
void Initialize();
public:
BasicLib::sint64 GetLastSendTime() const;
inline typename protocol::handler* Handler()
{
if (m_handlerstack.size() == 0)
{
return 0;
}
return m_handlerstack.top();
}
void BufferData(const char* p_buffer, int p_size);
void SendBuffer();
void Receive();
inline BasicLib::sint64 GetLastReceiveTime() const
{
return m_lastReceiveTime;
}
inline void Close() { m_closed = true; }
void ClearHandlers()
{
if (Handler())
Handler()->Leave();
while (Handler())
{
delete Handler();
m_handlerstack.pop();
}
}
inline void CloseSocket()
{
DataSocket::Close();
ClearHandlers();
}
inline int GetDataRate() const
{
return m_lastdatarate;
}
inline int GetCurrentDataRate() const
{
return m_datarate / TIMECHUNK;
}
inline int GetBufferedBytes() const
{
return (int)m_sendbuffer.size();
}
inline BasicLib::sint64 GetCreationTime() const
{
return m_creationtime;
}
inline protocol& Protocol() { return m_protocol; }
inline bool Closed() { return m_closed; }
inline void SwitchHandler(typename protocol::handler* p_handler)
{
if (Handler())
{
Handler()->Leave();
delete Handler();
m_handlerstack.pop();
m_handlerstack.push(p_handler);
p_handler->Enter();
}
}
inline void AddHandler(typename protocol::handler* p_handler)
{
if (Handler())
Handler()->Leave();
m_handlerstack.push(p_handler);
p_handler->Enter();
}
inline void RemoveHandler()
{
Handler()->Leave();
delete Handler();
m_handlerstack.pop();
if (Handler())
{
Handler()->Enter();
}
}
protected:
protocol m_protocol;
std::stack<typename protocol::handler*> m_handlerstack;
std::string m_sendbuffer;
int m_datarate;
int m_lastdatarate;
BasicLib::sint64 m_lastReceiveTime;
BasicLib::sint64 m_lastSendTime;
BasicLib::sint64 m_creationtime;
// determine whether the send time should
// be checked
bool m_checksendtime;
char m_buffer[BUFFERSIZE];
bool m_closed;
};
template<class protocol>
Connection<protocol>::Connection()
{
Initialize();
}
template<class protocol>
Connection<protocol>::Connection(DataSocket& p_socket):DataSocket(p_socket)
{
Initialize();
}
template<class protocol>
void Connection<protocol>::Initialize()
{
m_datarate = 0;
m_lastdatarate = 0;
m_lastReceiveTime = 0;
m_lastSendTime = 0;
m_checksendtime = false;
m_creationtime = BasicLib::GetTimeMS();
m_closed = false;
}
template<class protocol>
BasicLib::sint64 Connection<protocol>::GetLastSendTime()const
{
if (m_checksendtime)
{
return BasicLib::GetTimeMS() - m_lastSendTime;
}
return 0;
}
template<class protocol>
void Connection<protocol>::BufferData(const char* p_buffer, int p_size)
{
m_sendbuffer.append(p_buffer, p_size);
}
template<class protocol>
void Connection<protocol>::SendBuffer()
{
if (m_sendbuffer.size() > 0)
{
int sent = Send(m_sendbuffer.data(), (int)m_sendbuffer.size());
m_sendbuffer.erase(0, sent);
if (sent > 0)
{
m_lastSendTime = BasicLib::GetTimeMS();
m_checksendtime = false;
}
else {
if (!m_checksendtime)
{
m_checksendtime = true;
m_lastSendTime = BasicLib::GetTimeMS();
}
}
}
}
template<class protocol>
void Connection<protocol>::Receive()
{
int bytes = DataSocket::Receive(m_buffer, BUFFERSIZE);
BasicLib::sint64 t = BasicLib::GetTimeS();
if ((m_lastSendTime / TIMECHUNK) != (t / TIMECHUNK))
{
m_lastdatarate = m_datarate / TIMECHUNK;
m_datarate = 0;
m_lastReceiveTime = t;
}
m_datarate += bytes;
m_protocol.Translate(*this, m_buffer, bytes);
}
}
#endif // !CONNECTION_H