You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
 
 
 

107 lines
2.6 KiB

#include "windows_socket.h"
#include <iostream>
namespace Bk::Net {
int WindowsSocket::socket_count = 0;
WindowsSocket::WindowsSocket(int id, IpVersion ver, IpProtocol proto)
: id(id), ip_proto(proto), main(false)
{
char myIP[16] = " ";
socklen_t len = sizeof(addr);
getsockname(id, (struct sockaddr*)&addr, &len);
inet_ntop((int)ver, &addr, myIP, sizeof(myIP));
ip_addr = IpAddress(std::string(myIP, 16), ver);
}
WindowsSocket::WindowsSocket(IpAddress ip, int port, IpProtocol proto)
: ip_addr(ip), ip_proto(proto), main(true)
{
if (socket_count++ < 1)
{
WSADATA wsa_data;
int err;
err = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if (err != 0)
{
BK_CORE_TRACE("WSA failed : {0}", WSAGetLastError());
WSACleanup();
exit(EXIT_FAILURE);
}
}
//WindowsSocket creation step
if ((id = (int)socket((int)ip_addr.version, (int)ip_proto, 0)) < 0)
{
BK_CORE_TRACE("Socket failed : {0}", WSAGetLastError());
exit(EXIT_FAILURE);
}
addr.sin_addr = ip_addr.get_data();
addr.sin_family = (int)ip_addr.version;
addr.sin_port = htons(port);
}
WindowsSocket::~WindowsSocket()
{
if (main && socket_count-- < 1) WSACleanup();
closesocket(id);
}
bool WindowsSocket::init()
{
//Binding step
int status;
if ((status = bind((SOCKET)id, (struct sockaddr*)&addr, sizeof(addr)) < 0))
{
BK_CORE_TRACE("Binding failed : {0}", WSAGetLastError());
return false;
}
return true;
}
bool WindowsSocket::start(int cpt_conn = SOMAXCONN)
{
//Listening step
if (listen(id, cpt_conn) == SOCKET_ERROR) { BK_CORE_TRACE("Listening failed : {0}", WSAGetLastError()); return false; }
return true;
}
Socket* WindowsSocket::ack()
{
socklen_t addrlen = sizeof(addr);
return new WindowsSocket(accept((SOCKET)id, (struct sockaddr*)&addr, &addrlen), ip_addr.version, ip_proto));
}
bool WindowsSocket::conn()
{
if (connect(id, (struct sockaddr*)&addr, sizeof(addr)) < 0) { return false; }
return true;
}
bool WindowsSocket::hasConnection(int seconds, int microseconds) {
struct timeval tv = { seconds, microseconds };
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(id, &rfds);
return select(id + 1, &rfds, (fd_set*)0, (fd_set*)0, &tv) > 0;
};
void WindowsSocket::emit(std::vector<char> packet)
{
send((SOCKET)id, packet.data(), packet.size(), 0);
}
std::vector<char> WindowsSocket::obtain(int size)
{
std::vector<char> buffer;
buffer.resize(size);
int read_size = recv((SOCKET)id, buffer.data(), buffer.size() - 1, 0);
buffer.resize(read_size);
return buffer;
}
Socket* Socket::create(IpAddress ip, int port, IpProtocol proto)
{
return new WindowsSocket(ip, port, proto);
}
}