-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsocketlib2_accept.h
More file actions
98 lines (89 loc) · 2.87 KB
/
socketlib2_accept.h
File metadata and controls
98 lines (89 loc) · 2.87 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
//
// Created by ferenci84 on 5/14/2020.
//
#ifndef SOCKETLIB2_SOCKETLIB2_ACCEPT_H
#define SOCKETLIB2_SOCKETLIB2_ACCEPT_H
#include "socketlib2.h"
#include <future>
#include <string>
#include <iostream>
using namespace std;
bool accept(SOCKET sock, SOCKET& connsock, string& addr, unsigned short& port, int& error) {
struct sockaddr_in connectSAddr;
int addrLen = sizeof(connectSAddr);
cout << "accept connection" << endl;
connsock = accept(sock, (struct sockaddr *)&connectSAddr, &addrLen);
if (connsock==INVALID_SOCKET) {
error = WSAGetLastError();
return false;
}
port = connectSAddr.sin_port;
char addr_buf[64];
inet_ntop(connectSAddr.sin_family, &(connectSAddr.sin_addr), (char *) addr_buf, 64);
addr = string(addr_buf);
cout << "addr: " << addr << endl;
return true;
}
struct accept_result {
bool success{};
SOCKET sock{};
string addr;
unsigned short port{};
int error{};
};
class accept_connections {
SOCKET sock;
future<struct accept_result> accept_future;
bool future_in_progress;
bool connected;
struct accept_result res;
public:
accept_connections(SOCKET sock): sock(sock), connected(true), future_in_progress(false) {}
bool is_connected() {return connected;}
~accept_connections() {
if (future_in_progress) {
if (accept_future.wait_for(std::chrono::milliseconds(1000)) != future_status::ready) {
cout << "abandoning accept process" << endl;
accept_future._Abandon();
}
}
}
private:
struct accept_result accept() {
struct accept_result res;
res.success = ::accept(sock,res.sock,res.addr,res.port,res.error);
return res;
}
public:
bool poll_accept(int wait_for, bool restart = true) {
if (!this->is_connected()) return false;
bool start_task = false;
if (!future_in_progress) {
cout << "starting accept task" << endl;
accept_future = async(launch::async, &accept_connections::accept, this);
future_in_progress = true;
}
if (accept_future.wait_for(std::chrono::milliseconds(wait_for)) == future_status::ready) {
res = accept_future.get();
if (restart) {
cout << "restarting accept task" << endl;
accept_future = async(launch::async, &accept_connections::accept, this);
} else {
future_in_progress = false;
}
return true;
}
return false;
}
bool get_last_result(SOCKET& client_sock, string& addr, unsigned short& port, int& error) {
if (res.success) {
client_sock = res.sock;
addr = res.addr;
port = res.port;
} else {
error = res.error;
}
return res.success;
}
};
#endif //SOCKETLIB2_SOCKETLIB2_ACCEPT_H