Skip to content

Commit 0847c0f

Browse files
committed
Reimplemented client loop
1 parent 07274b4 commit 0847c0f

20 files changed

+259
-395
lines changed

.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
"ratio": "cpp",
5353
"future": "cpp",
5454
"mutex": "cpp",
55-
"thread": "cpp"
55+
"thread": "cpp",
56+
"bitset": "cpp",
57+
"map": "cpp",
58+
"regex": "cpp",
59+
"shared_mutex": "cpp"
5660
}
5761
}

client/MainConsole.cpp

Lines changed: 90 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <iostream>
44

55
#include <sys/eventfd.h>
6-
#include <sys/epoll.h>
6+
#include <sys/select.h>
77

88
#include <errno.h>
99
#include <unistd.h>
@@ -47,227 +47,136 @@ namespace simpleApp
4747
return 0;
4848
}
4949

50-
void cleanStdin()
51-
{
52-
// TODO
53-
}
54-
55-
int getFromStdin(char* buffer)
56-
{
57-
// TODO
58-
return 0;
59-
}
60-
6150
int MainConsole::consoleLoop()
6251
{
63-
int epollfd = epoll_create1(0);
64-
65-
if (epollfd == -1)
52+
if (this->breakEventFd == -1)
6653
{
67-
std::cout << "EPoll creation failed with code " << errno << std::endl << std::flush;
68-
return -1;
69-
}
70-
71-
epoll_event setupEvent;
72-
setupEvent.data.fd = this->breakEventFd;
73-
setupEvent.events = EPOLLIN | EPOLLET;
74-
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, this->breakEventFd, &setupEvent) == -1)
75-
{
76-
std::cout << "EPOLL_CTL_ADD of break event fd failed with code " << errno << std::endl << std::flush;
77-
close(epollfd);
54+
std::cout << "Break event is not set" << std::endl;
7855
return -1;
7956
}
8057

81-
setupEvent.data.fd = STDIN_FILENO;
82-
setupEvent.events = EPOLLIN | EPOLLET;
83-
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &setupEvent) == -1)
84-
{
85-
std::cout << "EPOLL_CTL_ADD of break event fd failed with code " << errno << std::endl << std::flush;
86-
epoll_ctl(epollfd, EPOLL_CTL_DEL, this->breakEventFd, nullptr);
87-
close(epollfd);
88-
return -1;
89-
}
58+
timeval tv;
59+
60+
tv.tv_sec = 5;
61+
tv.tv_usec = 0;
9062

9163
bool isExit = false;
92-
console_state currentState = console_state::protocol_selection;
93-
SessionClient* currentSession = nullptr;
64+
SessionClient * currentSession = nullptr;
65+
console_state currentState;
9466

95-
std::cout << "Select protocol: [u]dp or [t]cp - or press Ctrl+C for exit" << std::endl << std::flush;
96-
std::cout << " >> " << std::flush;
67+
auto switchState = [&currentState, &currentSession, &isExit](console_state newState)
68+
{
69+
// TODO
70+
};
71+
72+
switchState(console_state::protocol_selection);
9773

9874
while (!isExit)
9975
{
100-
const size_t eventsSize = 4;
101-
epoll_event events[eventsSize];
76+
fd_set fd_in;
77+
FD_ZERO(&fd_in);
10278

103-
console_state nextState = console_state::none;
79+
FD_SET(this->breakEventFd, &fd_in);
80+
FD_SET(STDIN_FILENO, &fd_in);
10481

105-
int len = epoll_wait(epollfd, events, eventsSize, -1);
106-
for(size_t i = 0; static_cast<int>(i) < len; i++)
82+
int largerFd = this->breakEventFd > STDIN_FILENO ? this->breakEventFd : STDIN_FILENO;
83+
if (currentSession != nullptr)
10784
{
108-
if (events[i].data.fd == this->breakEventFd)
109-
{
110-
switch (currentState)
111-
{
112-
case console_state::protocol_selection:
113-
nextState = console_state::none;
114-
isExit = true;
115-
break;
116-
117-
case console_state::msg_input:
118-
case console_state::wait_result:
119-
case console_state::connect_wait:
120-
delete currentSession;
121-
currentSession = nullptr;
122-
case console_state::address_input:
123-
nextState = console_state::protocol_selection;
124-
break;
125-
default:
126-
break;
127-
}
128-
129-
cleanStdin();
85+
auto sessionSocket = currentSession->getSocket();
86+
largerFd = sessionSocket > largerFd ? sessionSocket : largerFd;
87+
}
88+
89+
int selectResult = select(largerFd + 1, &fd_in, 0, 0, &tv);
13090

131-
break;
132-
}
91+
if (selectResult == -1)
92+
{
93+
std::cout << "Select failed with code " << errno;
94+
if (currentSession != nullptr)
95+
delete currentSession;
96+
return -1;
97+
}
13398

134-
// Non-console event and have session
135-
if (events[i].data.fd != STDIN_FILENO && currentSession != nullptr)
99+
if (currentSession != nullptr)
100+
{
101+
if (selectResult == 0)
136102
{
137-
//cleanStdin();
138-
139-
switch (currentState)
103+
auto result = currentSession->sendConnup();
104+
if (result.status != session_status::connup_up && result.status != session_status::connup_not_req)
140105
{
141-
case console_state::msg_input:
106+
if (result.status == session_status::connup_timeout)
107+
std::cout << std::endl << "Server does not response";
108+
else
109+
std::cout << std::endl << "Unknown error";
142110

143-
break;
144-
145-
default:
146-
break;
111+
if (result.err != 0)
112+
std::cout << " with code " << result.err << std::endl << std::flush;
113+
else
114+
std::cout << std::endl << std::flush;
115+
116+
switchState(console_state::address_input);
117+
118+
continue;
147119
}
148-
// TODO
149120
}
150-
151-
// Console input
152-
if (events[i].data.fd == STDIN_FILENO)
121+
122+
// Something came to socket without request
123+
if (FD_ISSET(currentSession->getSocket(), &fd_in))
153124
{
154-
char buffer[MESSAGE_MAX_BUFFER - sizeof(msg_headers)];
155-
auto len = getFromStdin(buffer);
125+
auto result = currentSession->proceed();
156126

157-
if (len < 1)
127+
switch (result.status)
158128
{
159-
cleanStdin();
129+
case session_status::proceed_msg_recv_fail:
130+
std::cout << "Message receiving failed";
160131
break;
161-
}
162-
163-
switch (currentState)
164-
{
165-
case console_state::protocol_selection:
166-
if (buffer[0] == 't')
167-
{
168-
currentSession = new SessionTcp(epollfd);
169-
nextState = console_state::address_input;
170-
}
171-
else if (buffer[0] == 'u')
172-
{
173-
currentSession = new SessionUdp(epollfd);
174-
nextState = console_state::address_input;
175-
}
176-
else
177-
{
178-
std::cout << "Incorrect choice" << std::endl << std::flush;
179-
}
132+
case session_status::proceed_disconnect:
133+
std::cout << "Session shutdown by server";
134+
break;
135+
case session_status::recv_wrong_length:
136+
std::cout << "Message with wrong length received";
137+
break;
138+
case session_status::proceed_server_error:
139+
std::cout << "Server error returned";
140+
break;
141+
case session_status::proceed_server_timeout:
142+
std::cout << "Received server timeout";
180143
break;
181-
182-
case console_state::address_input:
183-
{
184-
auto result = currentSession->init(std::string(buffer, len));
185-
switch (result.status)
186-
{
187-
case session_status::init_success:
188-
nextState = console_state::msg_input;
189-
break;
190-
191-
case session_status::init_udp_conn_wait:
192-
nextState = console_state::connect_wait;
193-
break;
194-
195-
default:
196-
std::cout << "Connection error" << std::endl << std::flush;
197-
delete currentSession;
198-
currentSession = nullptr;
199-
nextState = console_state::protocol_selection;
200-
break;
201-
}
202-
break;
203-
}
204-
case console_state::msg_input:
205-
{
206-
auto result = currentSession->proceed(events[i].data.fd, buffer, len);
207-
switch (result.status)
208-
{
209-
case session_status::proceed_msg_send:
210-
211-
break;
212-
213-
default:
214-
break;
215-
}
216-
}
217144
default:
145+
std::cout << "Unknown error";
218146
break;
219147
}
148+
149+
if (result.err != 0)
150+
std::cout << " with code " << result.err << std::endl << std::flush;
151+
else
152+
std::cout << std::endl << std::flush;
153+
154+
switchState(console_state::protocol_selection);
220155

221-
cleanStdin();
222-
break;
156+
continue;
223157
}
224158
}
225-
226-
// Switch state
227-
switch (nextState)
159+
else if (selectResult == 0)
228160
{
229-
case console_state::protocol_selection:
230-
{
231-
std::cout << "Select protocol: [u]dp or [t]cp - or press Ctrl+C for exit" << std::endl << std::flush;
232-
break;
233-
}
234-
235-
case console_state::address_input:
236-
{
237-
std::cout << "Input IP address of server. To change protocol press Ctrl+C" << std::endl << std::flush;
238-
break;
239-
}
240-
241-
case console_state::msg_input:
242-
{
243-
std::cout << "Connected to server. For disconnect press Ctrl+C" << std::endl << std::flush;
244-
break;
245-
}
246-
default:
247-
break;
161+
continue;
248162
}
249163

250-
if (nextState != console_state::none)
251-
currentState = nextState;
164+
if (FD_ISSET(this->breakEventFd, &fd_in))
165+
{
166+
if (currentState == console_state::protocol_selection)
167+
isExit = true;
168+
else
169+
switchState(console_state::protocol_selection);
170+
171+
continue;
172+
}
252173

253-
switch (currentState)
174+
if (FD_ISSET(STDIN_FILENO, &fd_in))
254175
{
255-
case console_state::protocol_selection:
256-
case console_state::address_input:
257-
case console_state::msg_input:
258-
std::cout << " >> " << std::endl;
259-
break;
260-
default:
261-
break;
176+
// TODO
262177
}
263178
}
264179

265-
if (currentSession != nullptr)
266-
delete currentSession;
267-
268-
epoll_ctl(epollfd, EPOLL_CTL_DEL, this->breakEventFd, 0);
269-
close(epollfd);
270-
271180
return 0;
272181
}
273182
}

0 commit comments

Comments
 (0)