snf.h: /* Removed long signature for the sake of posting. */ #include "snferror.h" #ifdef WIN32 // It's portable #include #else #include #include #include #include #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); } }; snferror.h: /* Removed long signature for the sake of posting. */ #include // strcat #include // 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 } example.cpp #include "snf.h" #include #include void main() { char mypage[] = "\n\nIf you are viewing this page, you are viewing a page from a HTTP server coded with Shell\'s Network Framework (or SNF for short)\n\n"; 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(); } }