C++

C++ And C# Sockets – Webserver refactored

3. January 2010

C++ Source Code

 

#include "Socket.h"
#include "HTTPAnswer.h"
 
using namespace std;
// Object files needs to link against Winsock2 Lib
#pragma comment(lib, "ws2_32.lib")
#define BUFFER_LENGTH 512 // Length of the recieve buffer - i needed to set it because sizeof(pointer) does always return 4 --> See recieve part
 
///// MAIN /////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
 
    // check parameters
    if(argc < 2 || (string)argv[1] != "-p") {
        cout << "Start Server with -p PORT\n";
        return -1;
    }
 
    #ifdef _WIN32
        // the path of the executable of this programm is passed as default parameter
        string spfad = argv[0]; // as first default param
        // But the name of the Programm is in the path ( c:\path\to\programm\programm.exe )
        spfad = spfad.substr(0,spfad.find_last_of("\\")); // this deletes everything behind the last backslash
    #else
        // for linux its working as follows
        char pathbuffer[PATH_MAX];
        readlink("/proc/self/exe", pathbuffer, PATH_MAX);
        string spfad = pathbuffer;
        spfad = spfad.substr(0,spfad.find_last_of("/")); // this deletes everything behind the last slash
    #endif
    // this path is needed later on to load html files and so on!
 
    int            readableSockets,bufferLength=0;
    vector<int>    readableSocketsList;
    char*        buffer;
    Socket*        socket;
    HTTPAnswer    answer;
 
    // create a new socket
    try {
        socket = new Socket();
        socket->setNonBlocking(true);
        socket->bindToPort(atoi(argv[2]));
    } catch(char* error) {
        cout << error << endl;
        return -1; // exit programm
    }
 
    while(true) { // server loop
        cout << "Waiting for connections\n";
        try {
            readableSockets = socket->getReadableDescriptors(&readableSocketsList); // get the sockets which are readable now
        } catch(char* e) {
            cout << e << endl;
            break; // terminate server
        }
        cout << readableSockets << " readable sockets found...\n";
        for(unsigned int i=0;i<readableSocketsList.size();i++) { // loop trough all readable sockets and process them
            cout << "processing socket" << readableSocketsList[i] << endl;
            if(readableSocketsList[i] == socket->getDescriptorNumber())
                socket->acceptConnections(); // readable socket is main socket - this means that someone is trying to connect
            else {
                // read data and send back response
                string sbuffer;
                bool boolContinue = true;
 
                do { // recieve until there is nothing left
                    buffer = new char[BUFFER_LENGTH];
                    memset(buffer,0,sizeof(buffer));
                    try {
                        int newBufferLength=socket->receiveData(readableSocketsList[i],buffer,BUFFER_LENGTH); // this is where sizeof(buffer) does not work (at least on ubuntu)
                        if (newBufferLength == -1) {
                            delete [] buffer;
                            break; // everything has been recieved. stop
                        }
 
                        bufferLength+=newBufferLength;
                        sbuffer.append(buffer,0,newBufferLength);
 
                        if(newBufferLength < BUFFER_LENGTH) // everything is recieved now (needed under ubuntu or it will recieve forever)
                            boolContinue = false;
                    } catch(char* e) {
                        cout << e << endl;
                        boolContinue = false;
                    }
 
                    delete [] buffer;
 
                } while(boolContinue);
 
                if(bufferLength > 0) {
                    // now analyse recieved data
                    if(sbuffer.substr(0,3) != "GET") {
                        answer.status=500;
                        answer.filename="/500.html";
                    } else {
                        answer.filename="/www"+sbuffer.substr(4,sbuffer.find_first_of(" ",4)-4); // this extracts the path to the file
                    }
 
                    try {
                        socket->sendData(readableSocketsList[i],answer.HTTPResponse(spfad)); // send data back to client
                    } catch(char* e) {
                        cout << e << endl;
                    }
                }
 
                socket->closeSocket(readableSocketsList[i]); // close connection
            }
        }
    }
    cout << "Shutting down server..." << endl;
    socket->closeSocket();
    delete socket;
}

C# Source Code 

using System;
6     
7    public class Globals
8    {
9        ///<summary>
10        /// Object files needs to link against Winsock2 Lib
11        ////// MAIN /////////////////////////////////////////////////////////////////
12        ///Rule R189: 'main' changed into 'Main'
13        ///</summary>
14        public static int Main(string[] argv)
15        {
16            cout << "Start Server with -p PORT\n";
17            return -1;
18            // the path of the executable of this programm is passed as default parameter
19            // as first default param
20            // But the name of the Programm is in the path ( c:\path\to\programm\programm.exe )
21            // this deletes everything behind the last backslash
22            spfad = spfad.substr(0,spfad.find_last_of("\\"));
23            // this path is needed later on to load html files and so on!
24            int readableSockets ,bufferLength = 0;
25            string buffer;
26            Socket * socket;
27            try {
28                socket.setNonBlocking(true);
29                socket.bindToPort(atoi(argv[2]));
30            }
31            catch(string  error){
32                cout << error << endl;
33                // exit programm
34                return -1;
35            }
36     
37     
38            while(true){
39                cout << "Waiting for connections\n";
40                try {
41                    // get the sockets which are readable now
42                    readableSockets = socket.getReadableDescriptors(readableSocketsList);
43                }
44                catch(string  e){
45                    cout << e << endl;
46                    // terminate server
47                    break;
48                }
49     
50     
51                cout << readableSockets << " readable sockets found...\n";
52                for(// loop trough all readable sockets and process them
53                uint i = 0;
54                i < readableSocketsList.size();(i)++)
55                {
56                    cout << "processing socket" << readableSocketsList[i ] << endl;
57                    if(readableSocketsList[i ] == socket.getDescriptorNumber())
58                    {
59                        // readable socket is main socket - this means that someone is trying to connect
60                        socket.acceptConnections();
61                    }
62                    else
63                    {
64                        // read data and send back response
65                        bool boolContinue = true;
66                        do{
67                            buffer = new char();
68                            memset(buffer ,0,4);
69                            try {
70                                // this is where sizeof(buffer) does not work (at least on ubuntu)
71                                int newBufferLength = socket.receiveData(readableSocketsList[i ],buffer ,BUFFER_LENGTH);
72                                if(newBufferLength == -1)
73                                {
74                                    buffer = null;
75                                    // everything has been recieved. stop
76                                    break;
77                                }
78                                bufferLength += newBufferLength;
79                                sbuffer.append(buffer ,0,newBufferLength);
80                                // everything is recieved now (needed under ubuntu or it will recieve forever)
81                                if(newBufferLength < BUFFER_LENGTH)
82                                {
83                                    boolContinue = false;
84                                }
85                            }
86                            catch(string  e){
87                                cout << e << endl;
88                                boolContinue = false;
89                            }
90     
91     
92                            buffer = null;
93                        }
94                        while(boolContinue);
95                        if(bufferLength > 0)
96                        {
97                            // now analyse recieved data
98                            if(sbuffer.substr(0,3) != "GET")
99                            {
100                                answer.status = 500;
101                                answer.filename = "/500.html";
102                            }
103                            else
104                            {
105                                // this extracts the path to the file
106                                answer.filename = "/www" + sbuffer.substr(4,sbuffer.find_first_of(" ",4) - 4);
107                            }
108                            try {
109                                // send data back to client
110                                socket.sendData(readableSocketsList[i ],answer.HTTPResponse());
111                            }
112                            catch(string  e){
113                                cout << e << endl;
114                            }
115     
116     
117                        }
118                        // close connection
119                        socket.closeSocket(readableSocketsList[i ]);
120                    }
121                }
122            }
123            ;
124            cout << "Shutting down server..." << endl;
125            socket.closeSocket();
126            socket = null;
127            //return value: Added during conversion from C++
128            return 0;
129        }
130    }

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

C# , C++