2018-09-24 10:43:20 +02:00
|
|
|
#include "socket.h"
|
2022-02-08 14:48:41 +01:00
|
|
|
#include "logger.h"
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <cstring>
|
|
|
|
#include <unistd.h>
|
2018-09-24 10:43:20 +02:00
|
|
|
|
|
|
|
Socket::Socket() : sock(-1) {}
|
|
|
|
|
|
|
|
Socket::~Socket() {
|
2022-02-08 14:44:53 +01:00
|
|
|
if (sock >= 0) {
|
2022-02-08 14:48:41 +01:00
|
|
|
::shutdown(sock, SHUT_RDWR);
|
|
|
|
::close(sock);
|
2022-02-08 14:44:53 +01:00
|
|
|
}
|
2018-09-24 10:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Socket::init(Type type) {
|
2022-02-08 14:44:53 +01:00
|
|
|
if (type == TCP) {
|
|
|
|
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
} else {
|
|
|
|
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
|
}
|
|
|
|
return sock >= 0;
|
2018-09-24 10:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Socket::close() {
|
2022-02-08 14:44:53 +01:00
|
|
|
if (sock >= 0) {
|
2022-02-08 14:48:41 +01:00
|
|
|
int result = ::close(sock);
|
2022-02-08 14:44:53 +01:00
|
|
|
sock = -1;
|
|
|
|
return result == 0;
|
|
|
|
}
|
|
|
|
return true;
|
2018-09-24 10:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Client::sendall(const void *data, size_t length) {
|
2022-02-08 14:44:53 +01:00
|
|
|
size_t sent = 0;
|
|
|
|
while (sent < length) {
|
|
|
|
int num = send(sock, data, length - sent, 0);
|
|
|
|
if (num < 0) {
|
|
|
|
close();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
sent += num;
|
|
|
|
data = (const char *) data + num;
|
|
|
|
}
|
|
|
|
return true;
|
2018-09-24 10:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Client::recvall(void *data, size_t length) {
|
2022-02-08 14:44:53 +01:00
|
|
|
size_t received = 0;
|
|
|
|
while (received < length) {
|
|
|
|
int num = recv(sock, data, length - received, 0);
|
|
|
|
if (num <= 0) {
|
|
|
|
close();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
received += num;
|
|
|
|
data = (char *) data + num;
|
|
|
|
}
|
|
|
|
return true;
|
2018-09-24 10:43:20 +02:00
|
|
|
}
|
|
|
|
|
2022-02-08 14:48:41 +01:00
|
|
|
struct sockaddr_kinnay {
|
|
|
|
uint16_t family;
|
|
|
|
uint16_t port;
|
|
|
|
uint32_t addr;
|
|
|
|
char zero[8];
|
|
|
|
};
|
2018-09-24 10:43:20 +02:00
|
|
|
|
|
|
|
bool Server::bind(int port) {
|
2022-02-08 14:44:53 +01:00
|
|
|
uint32_t reuseaddr = 1;
|
|
|
|
int result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, 4);
|
|
|
|
if (result < 0) {
|
|
|
|
close();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-02-08 14:48:41 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
struct sockaddr_in bindAddress;
|
|
|
|
memset(&bindAddress, 0, sizeof(bindAddress));
|
|
|
|
bindAddress.sin_family = AF_INET;
|
|
|
|
bindAddress.sin_port = htons(port);
|
|
|
|
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
|
|
|
result = ::bind(sock, (struct sockaddr *) &bindAddress, 16);*/
|
|
|
|
|
|
|
|
sockaddr_kinnay serverAddr = {0};
|
2022-02-08 14:44:53 +01:00
|
|
|
serverAddr.family = AF_INET;
|
|
|
|
serverAddr.port = port;
|
|
|
|
serverAddr.addr = 0;
|
|
|
|
|
2022-02-08 14:48:41 +01:00
|
|
|
result = ::bind(sock, (const struct sockaddr *) &serverAddr, 16);
|
2022-02-08 14:44:53 +01:00
|
|
|
if (result < 0) {
|
2022-02-08 14:48:41 +01:00
|
|
|
DEBUG_FUNCTION_LINE("Bind was not successful");
|
2022-02-08 14:44:53 +01:00
|
|
|
close();
|
|
|
|
return false;
|
|
|
|
}
|
2022-02-08 14:48:41 +01:00
|
|
|
DEBUG_FUNCTION_LINE("Bind was successful");
|
2022-02-08 14:44:53 +01:00
|
|
|
return true;
|
2018-09-24 10:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Server::accept(Client *client) {
|
2022-02-08 14:44:53 +01:00
|
|
|
int result = listen(sock, 1);
|
|
|
|
if (result < 0) {
|
2022-02-08 14:48:41 +01:00
|
|
|
DEBUG_FUNCTION_LINE("listen failed");
|
2022-02-08 14:44:53 +01:00
|
|
|
close();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int fd = ::accept(sock, 0, 0);
|
|
|
|
if (fd < 0) {
|
2022-02-08 14:48:41 +01:00
|
|
|
DEBUG_FUNCTION_LINE("accept failed");
|
2022-02-08 14:44:53 +01:00
|
|
|
close();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
client->sock = fd;
|
|
|
|
return true;
|
2018-09-24 10:43:20 +02:00
|
|
|
}
|