2013-11-19 12:38:13 +01:00
|
|
|
#include "Connection.h"
|
|
|
|
|
2013-11-19 13:42:50 +01:00
|
|
|
#include <winsock2.h>
|
2014-01-29 15:01:14 +01:00
|
|
|
#include <WS2tcpip.h>
|
2013-11-19 13:42:50 +01:00
|
|
|
#include <iostream>
|
2013-11-26 13:45:03 +01:00
|
|
|
#include <string>
|
2013-11-27 14:33:08 +01:00
|
|
|
#include <fcntl.h>
|
2013-11-19 13:42:50 +01:00
|
|
|
|
2013-11-25 11:39:38 +01:00
|
|
|
using namespace Oyster::Network;
|
2013-11-19 12:38:13 +01:00
|
|
|
|
2013-12-17 10:25:34 +01:00
|
|
|
int CloseSocket(int &socket)
|
|
|
|
{
|
|
|
|
if(socket == -1) return 0;
|
|
|
|
|
|
|
|
if(closesocket( socket ) == SOCKET_ERROR)
|
|
|
|
{
|
|
|
|
return WSAGetLastError();
|
|
|
|
}
|
|
|
|
|
|
|
|
socket = -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-12-04 12:41:25 +01:00
|
|
|
Connection::Connection()
|
|
|
|
{
|
2013-12-13 23:47:16 +01:00
|
|
|
this->socket = -1;
|
2013-12-17 10:25:34 +01:00
|
|
|
this->stillSending = false;
|
|
|
|
this->closed = true;
|
2013-12-04 12:41:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Connection::Connection(int socket)
|
|
|
|
{
|
|
|
|
this->socket = socket;
|
2013-12-17 10:25:34 +01:00
|
|
|
this->stillSending = true;
|
|
|
|
this->closed = false;
|
2013-12-04 12:41:25 +01:00
|
|
|
}
|
|
|
|
|
2013-11-19 12:38:13 +01:00
|
|
|
Connection::~Connection()
|
|
|
|
{
|
2013-12-17 10:25:34 +01:00
|
|
|
CloseSocket( this->socket );
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2014-01-29 15:01:14 +01:00
|
|
|
int Connection::Connect(ConnectionInfo info, bool blocking)
|
2014-01-28 09:00:02 +01:00
|
|
|
{
|
2014-01-29 15:01:14 +01:00
|
|
|
this->addr = info.addr;
|
|
|
|
this->socket = info.socket;
|
2014-01-28 09:00:02 +01:00
|
|
|
this->stillSending = true;
|
|
|
|
this->closed = false;
|
2014-01-29 15:01:14 +01:00
|
|
|
|
2014-01-28 09:00:02 +01:00
|
|
|
|
|
|
|
SetBlockingMode(blocking);
|
|
|
|
//connection succesfull!
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Connection::Connect(unsigned short port , const char serverName[], bool blocking)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2014-01-29 10:18:01 +01:00
|
|
|
if(this->socket == -1 || this->socket == 0) InitiateSocket();
|
|
|
|
|
2013-11-22 09:17:07 +01:00
|
|
|
struct hostent *hostEnt;
|
|
|
|
if((hostEnt = gethostbyname(serverName)) == NULL)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2013-11-26 13:45:03 +01:00
|
|
|
return WSAGetLastError();
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
2013-11-25 11:39:38 +01:00
|
|
|
|
2013-11-19 12:38:13 +01:00
|
|
|
struct sockaddr_in server;
|
|
|
|
server.sin_family = AF_INET;
|
|
|
|
server.sin_port = htons(port);
|
2013-11-22 09:17:07 +01:00
|
|
|
server.sin_addr.s_addr = *(unsigned long*) hostEnt->h_addr;
|
2013-11-19 12:38:13 +01:00
|
|
|
|
2013-11-25 12:14:01 +01:00
|
|
|
if(connect(this->socket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2013-11-26 13:45:03 +01:00
|
|
|
return WSAGetLastError();
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-12-04 12:41:25 +01:00
|
|
|
closed = false;
|
|
|
|
stillSending = true;
|
|
|
|
|
2014-01-28 09:00:02 +01:00
|
|
|
SetBlockingMode(blocking);
|
|
|
|
|
2013-11-19 12:38:13 +01:00
|
|
|
//connection succesfull!
|
2013-11-26 13:45:03 +01:00
|
|
|
return 0;
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-11-26 13:45:03 +01:00
|
|
|
int Connection::InitiateServer(unsigned short port)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2013-11-26 13:45:03 +01:00
|
|
|
int errorCode = 0;
|
|
|
|
|
2013-11-27 11:28:11 +01:00
|
|
|
if((errorCode = InitiateSocket()) != 0)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2013-11-26 13:45:03 +01:00
|
|
|
return errorCode;
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
struct sockaddr_in server;
|
|
|
|
server.sin_family = AF_INET;
|
|
|
|
server.sin_port = htons(port);
|
|
|
|
server.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
|
2013-11-25 11:39:38 +01:00
|
|
|
if(bind(this->socket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2013-11-26 13:45:03 +01:00
|
|
|
errorCode = WSAGetLastError();
|
2013-12-17 10:25:34 +01:00
|
|
|
CloseSocket(this->socket);
|
2013-11-26 13:45:03 +01:00
|
|
|
return errorCode;
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-11-22 09:17:07 +01:00
|
|
|
//not our Listen function! its trying to keep our socket open for connections
|
2013-11-25 11:39:38 +01:00
|
|
|
if(listen(this->socket, 5) == SOCKET_ERROR)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2013-11-26 13:45:03 +01:00
|
|
|
errorCode = WSAGetLastError();
|
2013-12-17 10:25:34 +01:00
|
|
|
CloseSocket(this->socket);
|
2013-11-26 13:45:03 +01:00
|
|
|
return errorCode;
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-12-04 12:41:25 +01:00
|
|
|
closed = false;
|
|
|
|
stillSending = true;
|
|
|
|
|
2013-11-19 12:38:13 +01:00
|
|
|
//Server started!
|
2013-11-26 13:45:03 +01:00
|
|
|
return 0;
|
2013-11-25 12:14:01 +01:00
|
|
|
}
|
|
|
|
|
2013-11-26 13:45:03 +01:00
|
|
|
int Connection::InitiateClient()
|
2013-11-25 12:14:01 +01:00
|
|
|
{
|
2013-11-27 11:28:11 +01:00
|
|
|
return InitiateSocket();
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-11-26 13:45:03 +01:00
|
|
|
int Connection::Disconnect()
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2014-01-14 10:15:50 +01:00
|
|
|
if(this->closed) return -1;
|
2014-01-07 10:26:09 +01:00
|
|
|
int val = CloseSocket(this->socket);
|
|
|
|
this->socket = -1;
|
|
|
|
this->closed = true;
|
|
|
|
this->stillSending = false;
|
|
|
|
return val;
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-12-16 08:59:38 +01:00
|
|
|
int Connection::Send(OysterByte &bytes)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2014-01-14 10:15:50 +01:00
|
|
|
if(this->closed) return -1;
|
|
|
|
|
2013-11-19 12:38:13 +01:00
|
|
|
int nBytes;
|
2013-11-22 09:24:44 +01:00
|
|
|
|
2013-12-16 08:59:38 +01:00
|
|
|
nBytes = send(this->socket, bytes, bytes.GetSize(), 0);
|
2013-11-22 09:17:07 +01:00
|
|
|
if(nBytes == SOCKET_ERROR)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2013-11-26 13:45:03 +01:00
|
|
|
return WSAGetLastError();
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-11-26 13:45:03 +01:00
|
|
|
return 0;
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-12-16 08:59:38 +01:00
|
|
|
int Connection::Recieve(OysterByte &bytes)
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2014-01-14 10:15:50 +01:00
|
|
|
if(this->closed) return -1;
|
2013-11-19 12:38:13 +01:00
|
|
|
int nBytes;
|
2013-11-25 19:05:28 +01:00
|
|
|
|
2013-12-16 08:59:38 +01:00
|
|
|
bytes.Resize(1000);
|
|
|
|
nBytes = recv(this->socket, bytes, 1000, 0);
|
2013-11-19 12:38:13 +01:00
|
|
|
if(nBytes == SOCKET_ERROR)
|
|
|
|
{
|
2013-12-16 08:59:38 +01:00
|
|
|
bytes.SetSize(0);
|
2013-11-26 13:45:03 +01:00
|
|
|
return WSAGetLastError();
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
2013-11-27 11:01:22 +01:00
|
|
|
else
|
|
|
|
{
|
2013-12-16 08:59:38 +01:00
|
|
|
bytes.SetSize(nBytes);
|
2013-11-27 11:01:22 +01:00
|
|
|
}
|
2013-11-19 12:38:13 +01:00
|
|
|
|
2013-11-26 13:45:03 +01:00
|
|
|
return 0;
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
//Listen will only return the correct socket or -1 for failure.
|
2014-01-29 15:01:14 +01:00
|
|
|
ConnectionInfo Connection::Listen()
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2014-01-29 15:01:14 +01:00
|
|
|
ConnectionInfo val = { 0 };
|
|
|
|
if(this->closed) return val;
|
2014-01-14 10:15:50 +01:00
|
|
|
|
2014-01-29 15:01:14 +01:00
|
|
|
SOCKADDR_IN client_info = { 0 };
|
|
|
|
int addrsize = sizeof(client_info);
|
|
|
|
|
|
|
|
if((val.socket = (int)accept(this->socket, (struct sockaddr*)&client_info, &addrsize)) == INVALID_SOCKET)
|
|
|
|
{
|
|
|
|
val.socket = WSAGetLastError();
|
|
|
|
}
|
|
|
|
else
|
2013-11-19 12:38:13 +01:00
|
|
|
{
|
2014-01-29 15:01:14 +01:00
|
|
|
val.addr = inet_ntoa(client_info.sin_addr);
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
|
|
|
|
2014-01-29 15:01:14 +01:00
|
|
|
return val;
|
2013-11-19 12:38:13 +01:00
|
|
|
}
|
2013-11-25 14:03:32 +01:00
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
bool Connection::IsSending()
|
2013-11-25 14:03:32 +01:00
|
|
|
{
|
2013-12-11 21:45:43 +01:00
|
|
|
return stillSending;
|
|
|
|
}
|
2013-11-25 14:03:32 +01:00
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
bool Connection::IsConnected()
|
|
|
|
{
|
|
|
|
return !closed;
|
2013-11-25 19:05:28 +01:00
|
|
|
}
|
2013-11-27 14:33:08 +01:00
|
|
|
|
2013-12-03 23:12:48 +01:00
|
|
|
int Connection::SetBlockingMode(bool blocking)
|
2013-11-27 14:33:08 +01:00
|
|
|
{
|
2013-12-03 23:12:48 +01:00
|
|
|
DWORD nonBlocking;
|
|
|
|
|
2013-11-27 14:33:08 +01:00
|
|
|
if(blocking)
|
|
|
|
{
|
2013-12-03 23:12:48 +01:00
|
|
|
nonBlocking = 0;
|
2013-11-27 14:33:08 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-12-03 23:12:48 +01:00
|
|
|
nonBlocking = 1;
|
|
|
|
}
|
2013-11-27 14:33:08 +01:00
|
|
|
|
2013-12-03 23:12:48 +01:00
|
|
|
int result = ioctlsocket(this->socket, FIONBIO, &nonBlocking);
|
|
|
|
if(result != 0)
|
|
|
|
{
|
|
|
|
return WSAGetLastError();
|
2013-11-27 14:33:08 +01:00
|
|
|
}
|
2013-12-03 23:12:48 +01:00
|
|
|
|
2013-12-16 08:59:38 +01:00
|
|
|
//Success
|
2013-12-11 21:45:43 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-01-29 15:01:14 +01:00
|
|
|
|
|
|
|
std::string Connection::GetIpAddress()
|
|
|
|
{
|
|
|
|
return this->addr;
|
|
|
|
}
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
///////////////////////////////////////
|
|
|
|
//Private functions
|
|
|
|
///////////////////////////////////////
|
|
|
|
int Connection::InitiateSocket()
|
|
|
|
{
|
2013-12-17 10:25:34 +01:00
|
|
|
if(this->socket != -1) return 0;
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
this->socket = (int)::socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
if(this->socket == SOCKET_ERROR)
|
|
|
|
{
|
|
|
|
return WSAGetLastError();
|
|
|
|
}
|
|
|
|
|
2014-01-15 11:03:25 +01:00
|
|
|
int flag = 1;
|
|
|
|
int result = setsockopt(this->socket, /* socket affected */
|
|
|
|
IPPROTO_TCP, /* set option at TCP level */
|
|
|
|
TCP_NODELAY, /* name of option */
|
|
|
|
(char *) &flag, /* the cast is historical cruft */
|
|
|
|
sizeof(int)); /* length of option value */
|
|
|
|
if (result < 0)
|
|
|
|
return -1;
|
|
|
|
|
2013-12-03 23:12:48 +01:00
|
|
|
return 0;
|
2013-11-27 14:33:08 +01:00
|
|
|
}
|