02-13-2012, 09:19 PM
Still in progress and requires lots of touching up, but it works for basic stuff. Not very OOP'ish and needs to be broken up _a lot_. So, don't expect anything special. It works on Linux & Windows. I haven't done any tests on anything but Ubuntu 11.10 & Win7.
And I guess here is some of it in action.
The above produces a neat little header we get from cloudflare by trying to request this site . Guess I was supposed to do more, but eh. Tis just a demonstration.
Code:
//socket.h
#ifndef SOCKET_H
#define SOCKET_H
#if defined _WIN32
#define _WIN32_WINNT 0x501
#include <ws2tcpip.h>
#include <winsock2.h>
#elif defined __linux
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#endif
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
class Socket
{
public:
Socket();
int connect(const std::string host_name, const std::string port_num);
int send(const std::string send_string);
virtual int recv();
void sock_err(const std::string err_string);
template<typename T>std::string tos(T x);
virtual ~Socket();
Socket operator<< (const std::string x);
Socket operator<< (const char* x);
Socket operator<< (const int x);
Socket operator<< (const float x);
Socket operator<< (const bool x);
Socket operator<< (const double x);
// Variables
std::string recv_string;
char buf[255];
int bytes_recv;
#if defined _WIN32
SOCKET sock;
#elif defined __linux
int sock;
#endif
struct addrinfo *ai;
protected:
private:
};
Socket::Socket()
{
#if defined _WIN32
WSADATA wsa;
if(WSAStartup(0x202, &wsa) != 0) sock_err("WSAStartup Error");
#endif
}
int Socket::connect(const std::string host_name, const std::string port_num)
{
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
int gai_error = getaddrinfo(host_name.c_str(), port_num.c_str(), &hints, &ai);
if(gai_error != 0)
{
std::cout << "getaddrinfo failed:\n" << gai_strerror(gai_error) << std::endl;
exit(0);
}
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock == INVALID_SOCKET) sock_err("Socket Creation Failure");
if(::connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) sock_err("Connect Error");
freeaddrinfo(ai);
return 0;
}
int Socket::send(const std::string send_string)
{
int x = ::send(sock, send_string.c_str(), send_string.length(), 0);
if(x == -1) sock_err("Send failed");
return x;
}
int Socket::recv()
{
memset(buf, 0, 255);
bytes_recv = ::recv(sock, buf, 254, 0);
if (bytes_recv < 0) sock_err("Recv Error: ");
recv_string = buf;
return bytes_recv;
}
void Socket::sock_err(const std::string err_string)
{
#if defined _WIN32
std::cout << err_string << "\n" << WSAGetLastError() << std::endl;
#elif defined __linux
perror(err_string.c_str());
#endif
freeaddrinfo(ai);
exit(0);
}
template<typename T>
std::string Socket::tos(T x)
{
std::stringstream tamp;
tamp << x;
return tamp.str();
}
Socket::~Socket()
{
// I have no idea what I am doing...
}
Socket Socket::operator<< (const std::string x) { Socket::send(x); return *this; }
Socket Socket::operator<< (const int x) { Socket::send(Socket::tos(x)); return *this; }
Socket Socket::operator<< (const float x) { Socket::send(Socket::tos(x)); return *this; }
Socket Socket::operator<< (const char* x) { Socket::send(x); return *this; }
Socket Socket::operator<< (const bool x) { Socket::send(Socket::tos(x)); return *this; }
Socket Socket::operator<< (const double x) { Socket::send(Socket::tos(x)); return *this; }
#endif // SOCKET_H
And I guess here is some of it in action.
Code:
#include <iostream>
#include "socket.h"
using namespace std;
int main()
{
Socket sock;
sock.connect("supportforums.net","80");
sock << "GET / HTTP/1.0\r\n\r\n";
while(sock.recv())
{
cout << sock.recv_string;
}
return 0;
}
The above produces a neat little header we get from cloudflare by trying to request this site . Guess I was supposed to do more, but eh. Tis just a demonstration.