-
Notifications
You must be signed in to change notification settings - Fork 0
/
my_socket.cpp
116 lines (91 loc) · 3.35 KB
/
my_socket.cpp
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
#include "my_socket.h"
#include <stdexcept>
#include <ws2tcpip.h>
#include <winsock2.h>
#include <iostream>
#define SOCKET_TERMINATE_CHAR '\0'
const char* MySocket::endMessage = ":end";
MySocket* MySocket::createConnection(std::string hostName, short port) {
WSADATA wsaData;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
throw std::runtime_error("WSAStartup failed with error: " + std::to_string(iResult) + "\n");
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(hostName.c_str(), std::to_string(port).c_str(), &hints, &result);
if (iResult != 0) {
WSACleanup();
throw std::runtime_error("getaddrinfo failed with error: " + std::to_string(iResult) + "\n");
}
// Create a SOCKET for connecting to server
SOCKET connectSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (connectSocket == INVALID_SOCKET) {
WSACleanup();
throw std::runtime_error("socket failed with error: " + std::to_string(WSAGetLastError()) + "\n");
}
// Connect to server
iResult = connect(connectSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(connectSocket);
connectSocket = INVALID_SOCKET;
}
freeaddrinfo(result);
if (connectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
throw std::runtime_error("Unable to connect to server.\n");
}
return new MySocket(connectSocket);
}
MySocket::MySocket(SOCKET socket) :
connectSocket(socket) {
}
MySocket::~MySocket() {
if (this->connectSocket != INVALID_SOCKET) {
closesocket(this->connectSocket);
this->connectSocket = INVALID_SOCKET;
}
WSACleanup();
}
void MySocket::sendData(const std::string &data) {
size_t data_length = data.length();
char* buffer = (char*)calloc(data_length + 1, sizeof(char));
memcpy(buffer, data.c_str(), data_length);
buffer[data_length] = SOCKET_TERMINATE_CHAR;
int iResult = send(connectSocket, buffer, data_length + 1, 0 );
if (iResult == SOCKET_ERROR) {
throw std::runtime_error("send failed with error: " + std::to_string(WSAGetLastError()) + "\n");
}
free(buffer);
buffer = NULL;
}
void MySocket::sendEndMessage() {
this->sendData(this->endMessage);
}
std::string MySocket::receiveData() {
char buffer[1024];
int bytesRead;
// Receive data from the socket
bytesRead = recv(connectSocket, buffer, sizeof(buffer), 0);
if (bytesRead == SOCKET_ERROR) {
throw std::runtime_error("recv failed with error: " + std::to_string(WSAGetLastError()) + "\n");
}
// Process the received data
std::string receivedData(buffer, bytesRead);
size_t terminatePos = receivedData.find(SOCKET_TERMINATE_CHAR);
if (terminatePos != std::string::npos) {
// Remove the termination character from the string
receivedData.erase(terminatePos);
}
std::cout << "Received data from the server: " << receivedData << std::endl;
return receivedData;
}
#undef SOCKET_TERMINATE_CHAR