Code:
#include "rSocket.h"
#include <iostream>
#include <sstream>
using std::string;
using std::stringstream;
using std::cout;
using std::endl;
void Socket::Initialize()
{
WSADATA wsd;
if (WSAStartup(MAKEWORD(2,2),&wsd))
{
cout << "Unable to setup Winsock.";
}
}
Socket::Socket() : s(0)
{
Initialize();
Blocking = true;
Timeout = 0;
s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
cout << "Invalid Socket: " << WSAGetLastError();
}
BOOL opt = TRUE;
int optl = sizeof(BOOL);
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(const char*)&opt,optl) == SOCKET_ERROR)
{
cout << "Setting reusable address option failed: " << WSAGetLastError();
}
}
Socket::Socket(SOCKET i) : s(i)
{
Initialize();
if (s != 0)
{
BOOL opt = TRUE;
int optl = sizeof(BOOL);
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(const char*)&opt,optl) == SOCKET_ERROR)
{
cout << "Setting reusable address option failed: " << WSAGetLastError();
}
}
else
{
cout << "Socket supplied was invalid. " << WSAGetLastError();
}
Blocking = true;
Timeout = 0;
}
Socket::Socket(int BindPort) : s(0)
{
Initialize();
Blocking = true;
Timeout = 0;
s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
cout << "Invalid Socket: " << WSAGetLastError();
}
BOOL opt = TRUE;
int optl = sizeof(BOOL);
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(const char*)&opt,optl) == SOCKET_ERROR)
{
cout << "Setting reusable address option failed: " << WSAGetLastError();
}
struct addrinfo* portaddr, hints;
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL,BindPort,&hints,&result);
if(bind(s,result->ai_addr,result->ai_addrlen) != 0)
{
cout << "Bind error: " << WSAGetLastError() << std::endl;
}
}
Socket::~Socket()
{
Close();
}
std::string Socket::Receive()
{
if (Timeout > 0) //If a timeout is set, then use select to wait
{
fd_set Sockets;
Sockets.fd_count = 1;
Sockets.fd_array[0] = s;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = Timeout;
int sel = select(s+1,&Sockets,NULL,NULL,&tv);
if (sel)
{
std::string retval;
char buf[1024];
while (true)
{
u_long arg = 0;
if (ioctlsocket(s,FIONREAD,&arg) != 0)
{
stringstream error;
error << WSAGetLastError();
return error.str();
}
if (arg > 1024)
arg = 1024;
int received = recv(s,buf,arg,0);
if (received > 0)
{
std::string t;
t.assign(buf,received);
retval += t;
break;
}
}
return retval;
}
else
{
return "";
}
}
else
{
std::string retval;
char buf[1024];
while (true)
{
u_long arg = 0;
if (ioctlsocket(s,FIONREAD,&arg) != 0)
{
stringstream error;
error << WSAGetLastError();
return error.str();
}
if (arg > 1024)
arg = 1024;
int received = recv(s,buf,arg,0);
if (received > 0)
{
std::string t;
t.assign(buf,received);
retval += t;
break;
}
if (received == -1)
{
cout << "Receive fail: " << WSAGetLastError() << endl;
break;
}
}
return retval;
}
}
int Socket::Send(const std::string& msg)
{
int sent = 0;
if (Timeout > 0) //If a timeout is set, then use select to wait
{
fd_set Sockets;
Sockets.fd_count = 1;
Sockets.fd_array[0] = s;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = Timeout;
while (true)
{
unsigned int sel = select(s+1,NULL,&Sockets,NULL,&tv);
if (sel)
{
while (sent < msg.length())
{
sent += send(s,msg.c_str(),msg.length(),0);
}
}
}
}
else
{
while (sent < msg.length())
{
sent += send(s,msg.c_str(),msg.length(),0);
}
}
return sent;
}
bool Socket::ConnectToHTTPHost(const std::string& host)
{
hostent* he;
if ((he = gethostbyname(host.c_str())) == 0)
{
cout << errno;
return false;
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
addr.sin_addr = *((in_addr *)he->h_addr);
memset(&(addr.sin_zero),0,8);
if (connect(s,(sockaddr *) &addr, sizeof(sockaddr)) != 0)
{
cout << WSAGetLastError();
return false;
}
return true;
}
bool Socket::ConnectToHost(const std::string& host, int port)
{
hostent* he;
if ((he = gethostbyname(host.c_str())) == 0)
{
cout << errno;
return false;
}
struct addrinfo* portaddr, hints;
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(host.c_str(),port,&hints,&result);
if (connect(s,result->ai_addr,result->ai_addrlen) != 0)
{
cout << WSAGetLastError();
return false;
}
return true;
}
bool Socket::Listen(int NumConn)
{
int ret = listen(s,NumConn);
if (ret == SOCKET_ERROR)
return false;
return true;
}
Socket Socket::Accept()
{
if (Timeout > 0) //If a timeout is set, then use select to wait
{
fd_set Sockets;
Sockets.fd_count = 1;
Sockets.fd_array[0] = s;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = Timeout;
int sel = select(s+1,&Sockets,NULL,NULL,&tv);
if (sel)
{
SOCKET newConn = accept(s,0,0);
Socket ret(newConn);
return ret;
}
else
{
return Socket(0);
}
}
else //just carry on normally
{
SOCKET newConn = accept(s,0,0);
Socket ret(newConn);
return ret;
}
}
void Socket::Drop()
{
closesocket(s);
}
int Socket::SetBlocking(bool blocking)
{
u_long sets = 1;
if (blocking)
{
sets = 0;
Timeout = 0;
}
Blocking = sets > 0 ? false : true;
int ret = ioctlsocket(s,FIONBIO,&sets);
return ret;
}
void Socket::SetTimeout(int ms)
{
Timeout = ms * 1000;
}
void Socket::Close()
{
closesocket(s);
}
SOCKET Socket::GetSocketFileDescriptor()
{
return s;
}
[/spoiler]