-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.cpp
More file actions
67 lines (52 loc) · 1.63 KB
/
server.cpp
File metadata and controls
67 lines (52 loc) · 1.63 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
#include "server.hpp"
#include "common.hpp"
#include <sstream>
#include <unistd.h>
#include <time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
mirror_server::mirror_server(int port) {
listen_socket_ = ::socket(AF_INET, SOCK_STREAM, 0);
if ( listen_socket_ < 0 ) {
__THROW_EXCEPTION_WITH_LOCATION("Can't create socket")
}
struct sockaddr_in server_addr = {};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if ( ::bind(listen_socket_, (sockaddr*)&server_addr, sizeof(server_addr)) < 0 ) {
__THROW_EXCEPTION_WITH_LOCATION("Can't bind socket to port " << port);
}
if ( ::listen( listen_socket_, 0 ) != 0 ) {
__THROW_EXCEPTION_WITH_LOCATION("Can't start listening");
}
}
mirror_server::~mirror_server() {
}
void mirror_server::do_serve() {
int connection_fd = ::accept(listen_socket_, NULL, NULL);
if (connection_fd < 0) {
__THROW_EXCEPTION_WITH_LOCATION("Can't accept connection");
}
for ( ; ; ) {
union {
struct timespec ts;
uint8_t b[sizeof(timespec) / sizeof(uint8_t)];
} u = {};
int read_total = 0;
while (read_total != sizeof(u)) {
int bytes_to_read = (int)sizeof(u) - read_total;
auto read = ::read(connection_fd, &u.b[read_total], bytes_to_read);
if (read == 0) {
__THROW_EXCEPTION_WITH_LOCATION("No more data");
}
read_total += read;
}
auto written = ::write(connection_fd, u.b, sizeof (u));
if ( written != sizeof(u) ) {
::close(connection_fd);
__THROW_EXCEPTION_WITH_LOCATION("Can't write all data to socket");
}
}
::close(connection_fd);
}