Support Forums

Full Version: Simple in progress socket library
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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.

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 Big Grin. Guess I was supposed to do more, but eh. Tis just a demonstration.
Seems simple, at least you've put it into ONE header file up to this point which is somewhat more OOP, where most people I see don't use ANY.
(02-14-2012, 07:10 AM)AceInfinity Wrote: [ -> ]Seems simple, at least you've put it into ONE header file up to this point which is somewhat more OOP, where most people I see don't use ANY.

I plan on dividing it up into at least 3 or 4 different files with some of the stuff here and some things I got floating in my head.
You won't get much on C++ feedback here as our coding section seems more limited to VB.NET than C++ here Smile I may be you're only member here that might be able to give you programming related feedback, but others may only just ask questions and tell you how cool what you're doing is lol.

I haven't seen too many C++ programmers here though, and the ones that were here must have left.