-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsubscriber.cpp
More file actions
209 lines (169 loc) · 6.85 KB
/
Copy pathsubscriber.cpp
File metadata and controls
209 lines (169 loc) · 6.85 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
#include <iostream>
#include <cstring>
#include <vector>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include "cli_checks_utils.h"
#include "connect_utils.h"
#include "alex_simple_protocol.h"
#include "client.h"
#define SUBSCRIBE_FORMAT_MESSAGE "Subscribed to topic "
#define UNSUBSCRIBE_FORMAT_MESSAGE "Unsubscribed from topic "
// Epoll constants
constexpr int MAX_EPOLL_ARRAY_SIZE = 102;
constexpr int MAX_CLIENT_MESSAGE_LEN = 80;
// Topic tree constants
constexpr int MAX_TOPIC_LEN = 51;
constexpr int MAX_UDP_MESSAGE_LEN = (51 + sizeof(int) + 1501);
#include "Epoll.h"
#include "Socket.h"
int main(int argc, char const *argv[]) {
setvbuf(stdout, NULL, _IONBF, BUFSIZ);
// Input checks
if (argc != 4 ||
!is_ip_address(argv[2]) ||
!is_port_number(argv[3])) {
std::cerr << "Please use executable correctly\n";
return 1;
}
int port_number;
sscanf(argv[3], "%d", &port_number);
int yes = 1;
Client myself = Client(string(argv[1]), port_number, string(argv[2]));
// Client socket setup
Socket my_socket;
if (!my_socket.create_socket(AF_INET, SOCK_STREAM, 0) ||
!my_socket.set_socket_opt(IPPROTO_TCP, TCP_NODELAY, (char *) &yes, sizeof(int)) ||
!my_socket.connect_socket(argv[2], port_number)) return 1;
send_connect_request(myself, my_socket.get_fd());
Epoll epoll_instance;
if (!epoll_instance.create_epoll()) return 1;
struct epoll_event tcp_event, stdin_event;
epoll_instance.config_epoll_event(tcp_event, my_socket.get_fd());
epoll_instance.config_epoll_event(stdin_event, STDIN_FILENO);
int events_array_capacity = MAX_EPOLL_ARRAY_SIZE;
vector<struct epoll_event> events_array(events_array_capacity);
bool will_resize = false;
while (true) {
if (will_resize) {
// if vector is close to full, double in size
events_array.resize(events_array_capacity * 2);
will_resize = false;
}
int n = epoll_instance.wait_for_events(events_array, events_array_capacity);
if (n == -1) {
std::cerr << "Error at epoll_wait!\n";
goto my_fail_exit;
}
if (n > events_array_capacity / 2)
will_resize = true;
for (int i = 0; i < n; i++) {
int fd = events_array[i].data.fd;
if (fd == my_socket.get_fd()) {
// Handle TCP message
// got response from server
string data = receive_data(my_socket.get_fd());
if (data == "EROARE DE ZILE MARI!" ||
data == "SOCKET INCHIS GRACEFULLY")
goto my_exit;
int op;
sscanf(data.c_str(), "%d", &op);
switch (op) {
case ASP_SEND_FAIL:
{
int dead;
int op2;
sscanf(data.c_str(), "%d%d", &dead, &op2);
if (op2 == ASP_CLIENT_CONNECT) {
// am fail pe connect
goto my_fail_exit;
}
}
break;
case ASP_SEND_SUCCESS:
{
int dead;
int op2;
sscanf(data.c_str(), "%d%d", &dead, &op2);
switch (op2) {
case ASP_CLIENT_SUBSCRIBE:
{
int dead1, dead2;
char topic[MAX_TOPIC_LEN];
sscanf(data.c_str(), "%d%d%s", &dead1, &dead2, topic);
cout << SUBSCRIBE_FORMAT_MESSAGE << topic << endl;
}
break;
case ASP_CLIENT_UNSUBSCRIBE:
{
int dead1, dead2;
char topic[MAX_TOPIC_LEN];
sscanf(data.c_str(), "%d%d%s", &dead1, &dead2, topic);
cout << UNSUBSCRIBE_FORMAT_MESSAGE << topic << endl;
}
break;
case ASP_CLIENT_EXIT:
{
// pot sa dau exit
goto my_exit;
}
break;
case ASP_CLIENT_CONNECT:
{
// pot sa dau connect
// las asa nu fac nimic
}
break;
default:
break;
}
}
break;
case ASP_SEND_BUFFER:
{
// The UDP data was sent succesfully
string output = string(data.c_str() + 2);
cout << output << endl;
}
break;
case ASP_QUIT:
goto my_exit;
break;
default:
break;
}
} else if (fd == STDIN_FILENO)
{
char client_message[MAX_CLIENT_MESSAGE_LEN];
fgets(client_message, MAX_CLIENT_MESSAGE_LEN, stdin);
char cmd[20];
sscanf(client_message, "%s", cmd);
if (strcmp(cmd, "exit") == 0) {
send_exit(myself, my_socket.get_fd());
// wait for server response
// goto my_exit;
} else if (strcmp(cmd, "subscribe") == 0) {
char topic[MAX_TOPIC_LEN];
sscanf(client_message + strlen(cmd), "%s", topic);
send_sub_unsub(myself, ASP_CLIENT_SUBSCRIBE, string(topic), my_socket.get_fd());
// wait server response
} else if (strcmp(cmd, "unsubscribe") == 0) {
char topic[MAX_TOPIC_LEN];
sscanf(client_message + strlen(cmd), "%s", topic);
send_sub_unsub(myself, ASP_CLIENT_UNSUBSCRIBE, string(topic), my_socket.get_fd());
// wait server response
} else {
// printf("Some other command:\n%s\n", client_message);
}
}
}
}
my_exit:
return 0;
my_fail_exit:
return 1;
}