-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathTcpSocket.cpp
More file actions
107 lines (86 loc) · 2.75 KB
/
Copy pathTcpSocket.cpp
File metadata and controls
107 lines (86 loc) · 2.75 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
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: TcpSocket.cpp
* Author: kubatek94
*
* Created on 16 March 2016, 14:22
*/
#include "TcpSocket.h"
TcpSocket::TcpSocket(int socket, struct sockaddr_in address) : socket(socket), address(address) {}
TcpSocket::~TcpSocket() {
stop();
}
void TcpSocket::start(Type type) {
if (!runServer) {
runServer = true;
if (type == Type::ASYNC) {
server = std::thread(&TcpSocket::startServer, this);
} else {
startServer();
}
}
}
void TcpSocket::stop() {
if (runServer) {
runServer = false;
if (server.joinable()) {
server.join();
}
closeSocket();
}
}
void TcpSocket::startServer() {
while (runServer) {
//read message
try {
std::unique_ptr<Message::Message> message = getMessage();
if (onMessageCallback) {
onMessageCallback(this, std::move(message));
}
} catch (std::runtime_error e) {
runServer = false;
closeSocket();
std::cout << "Client " << getAddress() << " disconnected because: " << e.what() << std::endl;
}
}
}
std::unique_ptr<Message::Message> TcpSocket::getMessage() {
int readBytes = 0;
jbyte header[2];
//read the header
readBytes = read(socket, &header, 2);
if (readBytes < 0 || readBytes != 2) {
throw std::runtime_error("Cannot read message header");
}
std::unique_ptr<Message::Message> message = Message::MessageFactory::makeMessage(static_cast<Message::Message::Type>((int)header[0]), (int)header[1]);
if (message->getDataLength() > 0) {
MessageBuffer* buffer = message->getBuffer();
buffer->resize(message->getLength());
readBytes = read(socket, &(buffer->getBuffer().data()[2]), message->getDataLength());
buffer->setWritePos(message->getLength());
if (readBytes < 0 || readBytes != message->getDataLength()) {
throw std::runtime_error("Cannot read message body");
}
}
return message;
}
void TcpSocket::closeSocket() {
if (socketOpen) {
socketOpen = false;
close(socket);
}
}
void TcpSocket::onMessage(std::function<void(TcpSocket*,std::unique_ptr<Message::Message>)> onMessageCallback) {
this->onMessageCallback = onMessageCallback;
}
std::string TcpSocket::getAddress() {
if (ipAddress.empty()) {
char* ip = inet_ntoa(address.sin_addr);
ipAddress = std::string(ip);
}
return ipAddress;
}