A Simple Sockets Framework





8
Date Submitted Mon. Oct. 9th, 2006 6:46 AM
Revision 1 of 1
Helper shell
Tags CPlusPlus | Sockets | Winsock
Comments 0 comments
I made this a little while back for a friend who was having trouble learning sockets. Below are snf.h, snferror.h and example.cpp (a little example).

The example opens a "web server" at port 8080 on the machine. However, it displays just one page.

Have fun!

/* Removed long signature for the sake of posting.
 */


#include "snferror.h"

#ifdef WIN32            // It's portable
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

#define TCP          5000 // not defined this way for any reason, move along
#define UDP          5001

class snfc {
        int errormode;

        bool initcalled;
        bool client_made;
        bool server_made;

        int s; // our socket

        short port; // the port for our server to run on
                       
        int bl; // int for bind and listen
        int sr; // int for send and recv (and connect)
        int ac; // int for accept

        struct sockaddr_in cstruct; // struct used for certain calls
        struct sockaddr_in cli;     // stores client info
        int clilen;                 // eventually set (needed for accept)

        public:
                void changemode(int mode)
                {
                        if(mode > -1 && mode < TOTAL_MODES)
                                errormode = mode;
                }

                int init() // take care of all of that annoying stuff
                {
                        if(initcalled == true)
                                return snferror(INIT_CALLED, errormode);

                        error_start();
                        changemode(PRINT_RETURN);
                        client_made = false;
                        server_made = false;
                        initcalled  = true;

                        return 0;
                }

                int makeclient(short port, char ip[], int ipproto)
                {
                        if(server_made == true || client_made == true)
                                return snferror(MULTIPLE_SOCK, errormode);

                        if(initcalled != true)
                                return snferror(INIT_NOCALL, errormode);

                        cstruct.sin_family = AF_INET;
                        cstruct.sin_port = htons(port);
                        cstruct.sin_addr.s_addr = inet_addr(ip);
                               
                        WORD wsaversion = MAKEWORD(2, 2);
                        WSADATA wsadata;
                        if(WSAStartup(wsaversion, &wsadata) != 0)
                                return snferror(STARTUP_ERROR, errormode);
                       
                        if(ipproto == TCP)
                                s = socket(AF_INET, SOCK_STREAM, 0);
                        else if(ipproto == UDP)
                                s = socket(AF_INET, SOCK_DGRAM, 0);

                        if(s == INVALID_SOCKET)
                                return snferror(SOCKET_ERROR, errormode);
                       
                        sr = connect(s, (struct sockaddr *)&cstruct, sizeof(cstruct));
                        if(sr)
                                return snferror(CONNECT_ERROR, errormode);

                        client_made = true;

                        return SUCESS;
                }

                int makeserver(short port, int ipproto)
                {
                        if(server_made == true || client_made == true)
                                return snferror(MULTIPLE_SOCK, errormode);

                        if(initcalled != true)
                                return snferror(INIT_NOCALL, errormode);
                        port = port;
                        cstruct.sin_family = AF_INET;
                        cstruct.sin_port = htons(port);
                        cstruct.sin_addr.s_addr = htonl(INADDR_ANY);
                               
                        WORD wsaversion = MAKEWORD(2, 2);
                        WSADATA wsadata;
                        if(WSAStartup(wsaversion, &wsadata) != 0)
                                return snferror(STARTUP_ERROR, errormode);
               
                        if(ipproto == TCP)
                                s = socket(AF_INET, SOCK_STREAM, 0);
                        else if(ipproto == UDP)
                                s = socket(AF_INET, SOCK_DGRAM, 0);

                        if(s == INVALID_SOCKET)
                                return snferror(SOCK_ERROR, errormode);
                        bl = bind(s, (struct sockaddr *)&cstruct, sizeof(cstruct));
                        if(bl != 0)
                                return snferror(BIND_ERROR, errormode);

                        server_made = true;

                        return SUCESS;
                }

                int getclient(int max)
                {
                        if((server_made != true && client_made == false) ||
                                (server_made == false && client_made != true) ||
                                (server_made != true && client_made != true))
                                return snferror(SERCLI_NOMADE, errormode);

                        clilen = sizeof(cli); // needed for accept

                        bl = listen(s, max);
                        if(bl)
                                return snferror(LISTEN_ERROR, errormode);
                        ac = accept(s, (struct sockaddr *)&cli, &clilen);
                        if(ac == INVALID_SOCKET)
                                return snferror(ACCEPT_ERROR, errormode);

                        return SUCESS;
                }

                int snfsend(const char FAR *data)
                {
                        if((server_made != true && client_made == false) ||
                                (server_made == false && client_made != true) ||
                                (server_made != true && client_made != true))
                                return snferror(SERCLI_NOMADE, errormode);
                        if(server_made == true)
                                sr = send(ac, data, strlen(data), 0);
                        if(client_made == true)
                                sr = send(s, data, strlen(data), 0);

                        if(sr == -1)
                                return snferror(SEND_ERROR, errormode);

                        return sr;
                }

                int snfrecv(char FAR *target, int max)
                {
                        if((server_made != true && client_made == false) ||
                                (server_made == false && client_made != true) ||
                                (server_made != true && client_made != true))
                                return snferror(SERCLI_NOMADE, errormode);
                       
                        if(server_made == true)
                                sr = recv(ac, target, max, 0);
                        if(client_made == true)
                                sr = recv(s, target, max, 0);

                        if(sr == -1)
                                return snferror(RECV_ERROR, errormode);

                        return sr;
                }
               
                char * clientip()
                {
                        if(server_made != true)
                        {
                                snferror(SERVER_NOMADE, errormode);
                                return "SNF_ERROR";
                        }

                        char *ourbuffer = (char *)calloc(18, sizeof(char));
                        sprintf(ourbuffer, "%s", inet_ntoa(cli.sin_addr));
                       
                        int where = strlen(inet_ntoa(cli.sin_addr));

                        ourbuffer[where] = NULL;

                        return ourbuffer;
                }

                void closesock()
                {
                        if(server_made == true)
                                closesocket(ac);

                        if(client_made == true)
                                closesocket(s);
                }
};
 

/* Removed long signature for the sake of posting.
 */


#include <string.h> // strcat
#include <stdio.h>  // printf

typedef char error_str[256];

#define STARTUP_ERROR      0
#define SOCK_ERROR                  1 // renamed from SOCKET_ERROR to avoid repeated definition
#define BIND_ERROR                  2
#define LISTEN_ERROR        3
#define ACCEPT_ERROR        4
#define CONNECT_ERROR      5
#define SEND_ERROR                  6
#define RECV_ERROR                  7
#define INIT_NOCALL               8
#define SERVER_NOMADE      9
#define CLIENT_NOMADE      10
#define SERCLI_NOMADE      11
#define INIT_CALLED               12
#define MULTIPLE_SOCK      13

#define SUCESS            2600

#define TOTAL_ERRORS        14

char errors[TOTAL_ERRORS][256];

void error_start()
{
        strcat(errors[STARTUP_ERROR]"There was an error while calling WSAStartup"                     );
        strcat(errors[SOCK_ERROR],     "There was an error while creating the socket"                    );
        strcat(errors[BIND_ERROR],     "There was an error while binding to the socket"                  );
        strcat(errors[LISTEN_ERROR],   "There was an error while listening on the socket"                );
        strcat(errors[ACCEPT_ERROR],   "There was an error while accepting a connection"                 );
        strcat(errors[CONNECT_ERROR]"There was an error while connecting to the host"                 );
        strcat(errors[SEND_ERROR],     "There was an error while sending data"                           );
        strcat(errors[RECV_ERROR],     "There was an error while recieving data"                         );
        strcat(errors[INIT_NOCALL],    "Function init() has not been called!"                            );
        strcat(errors[SERVER_NOMADE]"The client has not yet been made!"                               );
        strcat(errors[CLIENT_NOMADE]"The server has not yet been made!"                               );
        strcat(errors[SERCLI_NOMADE]"Neither a server nor a client has been made!"                    );
        strcat(errors[INIT_CALLED],    "Function init() has already been called!"                        );
        strcat(errors[MULTIPLE_SOCK]"A server or client is already in use. Please call flush() first.");
}

#define PRINT            0
#define STORE            1
#define RETURN        2
#define PRINT_STORE               3
#define PRINT_RETURN        4
#define STORE_RETURN        5
#define PRINT_STORE_RETURN      6

#define TOTAL_MODES               7

error_str errstr;

int snferror(int error, int mode)
{
        if(error > TOTAL_ERRORS || error < 0)
                return -1;

        if(mode == PRINT || mode == PRINT_STORE || mode == PRINT_RETURN || mode == PRINT_STORE_RETURN)
        {
                printf("SNF ERROR: %s\n", errors[error]);
                if(mode == PRINT_STORE)
                        strcat(errstr, errors[error]);
                else if(mode == PRINT_RETURN)
                        return error;
                else if(mode == PRINT_STORE_RETURN)
                {
                        strcat(errstr, errors[error]);
                        return error;
                }
        }
        else if(mode == STORE || mode == STORE_RETURN)
        {
                strcat(errstr, errors[error]);
                if(mode == STORE_RETURN)
                        return error;
        }
        else if(mode == RETURN)
                return error;

        return TOTAL_ERRORS + 1; // you didn't ask for a return
}
 

#include "snf.h"
#include <stdio.h>
#include <time.h>

void main()
{
        char mypage[] = "<html>\n<body>\n<b>If you are viewing this page, you are viewing a page from a HTTP server coded with Shell\'s Network Framework (or SNF for short)</b>\n</body>\n</html>";
        char mybuffer[1024];
        char response[4096];
        char formtime[128];
        time_t thetime;
        struct tm *timeinfo;

        snfc server;
        server.init();
        server.makeserver(8080, TCP);
        for(;;)
        {
                server.getclient(2);
                int where = server.snfrecv(mybuffer, 1023);
                char *clientip = server.clientip();

                mybuffer[where] = NULL;

                printf("Got a request from %s\n", clientip);

                time(&thetime);
                timeinfo = localtime(&thetime);

                strftime(formtime, sizeof formtime, "%a, %d %b %Y %X SST", timeinfo);

                sprintf(response, "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nTransfer-Encoding: chunked\r\nDate: %s\r\nContent-Type: text/html\r\nServer: ShellHTTPServer\r\n\r\ne2 \x0d\x0a\x0a%s", formtime, mypage);

                server.snfsend(response);
               
                server.closesock();
        }
}
 

Comments

There are currently no comments for this snippet.

Voting