Netzwerk
TCP/IP (Webserver)
6 Quellcode

Dieses Kapitel beinhaltet relevante Quelltextauszüge aus der Beispiel Implementierung. Der komplette Quelltext steht im Downloadbereich zur Vefügung.

 


6.1 Starten und Stoppen des Servers

void CHTTPServerDlg::OnButtonStart()

{

    int nPort ;

    char cPortNumber[MAX_LEN] ;

   

    m_pEditPort->GetWindowText (cPortNumber, MAX_LEN) ;

    nPort = atoi(cPortNumber) ;

    m_pServer->Start(nPort) ;

}

void CHTTPServerDlg::OnButtonStop()

{

    m_pServer->Stop() ; 

}

 


6.2 Die Server Klasse

Server::Server()

{

    server_socket = 0 ;

    theThread = 0 ;

}

 

Server::~Server()

{

    Stop();

}

void Server::Init()

{

    WSADATA wsa ;

    if (server_socket == 0)

    {

        if (WSAStartup(MAKEWORD (1,1), &wsa)!= 0)

        {

            MessageBox (NULL,"Fehler bei Init","Meldung",0) ;

        }

        else

        {

            if ( LOBYTE( wsa.wVersion ) != 1 ||

                 HIBYTE( wsa.wVersion ) != 1 )

            {

                MessageBox (NULL,"Fehler bei

                                 Socketversion","Meldung",0) ;

            }

            else

            {

                server_socket = socket(AF_INET, SOCK_STREAM,0);

            }

        }

    }

}

 

int Server::Start(int nPort)

{

    struct ServerParam *pServerParam ;

    if (theThread == 0)

    {

        Init() ;

        pServerParam = new (struct ServerParam) ;

        pServerParam->Socket = server_socket ;

        pServerParam->Port = nPort ;

        strcpy (pServerParam->DefaultFilename, "index.html") ;

        strcpy (pServerParam->DocumentRoot,

                "D:/Daten/HTTPServer/docs") ;

        theThread = _beginthread (ServerThread, 0,

                                   (void *) pServerParam) ;

    }

    return (0) ;

}

 

int Server::Stop()

{

 if (theThread != 0)

 {

  TerminateThread ((HANDLE) theThread, -1) ;

  closesocket (server_socket) ;

  server_socket = 0 ;

  theThread = 0 ;

 }

 return (0) ;

}

 


6.3 Der Server Thread

#define incopy(a) (*((struct in_addr *)a))

void ServerThread(void *pParam)

{

 int cs ;

 int client_size ;

 struct sockaddr_in addr ;

 struct sockaddr client ;

    struct hostent *hp ;

 char cHostname[1024] ;

 int nRet ;

 int x;

 int s ;

 struct WorkerParam *pWorkerParam ;

 struct ServerParam *pServerParam ;

 nRet = 0 ;

 cs = 0 ;

 pServerParam = (struct ServerParam *) pParam ;

 s = pServerParam->Socket ;

 

 memset ((void *) &addr, 0, sizeof (addr)) ;

 

 gethostname (cHostname, sizeof (cHostname)) ;

    hp = gethostbyname (cHostname) ;

    addr.sin_family = AF_INET ;

    addr.sin_port = htons(pServerParam->Port) ;

    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY) ;

 x = bind (s, (struct sockaddr *) &addr,

              sizeof(struct sockaddr_in)) ;

 x = listen (s, 3) ;

 while (cs != -1)

 {

  client_size = sizeof (struct sockaddr) ;

  cs = accept (s, &client, &client_size) ;

  if (cs == -1)

  {

   x = WSAGetLastError() ;

  }

        pWorkerParam = new (struct WorkerParam) ;

  pWorkerParam->Socket = cs ;

        strcpy (pWorkerParam->DefaultFilename,

                pServerParam->DefaultFilename) ;

        strcpy (pWorkerParam->DocumentRoot,

                pServerParam->DocumentRoot) ;

  memcpy (&(pWorkerParam->Client),&client, sizeof (client)) ;

  _beginthread (WorkerThread, 0, (void *) pWorkerParam) ;

 }

 closesocket (s) ;

    delete (pServerParam) ;

 _endthread() ;

}

 


6.4 Der Worker Thread

char cHeader[] =

    "HTTP/1.0 200 OK\r\n"

 "Server: Joern Lenhardt Web Development\r\n"

 "Connection: Close\r\n"

 "Content-Type: text/html\r\n\r\n" ;

void WorkerThread(void *pParam)

{

 struct WorkerParam *pWorkerParam ;

 char bufferWrite[MAX_LEN] ;

 char bufferRead[10*MAX_LEN] ;

    char tempRead[10*MAX_PATH] ;

 int len ;

 struct sockaddr_in *cli ;

 char cCrLf[3] ;

 char c2CrLf[5] ;

    char cRelativeFilename[MAX_LEN] ;

    char cAbsoluteFilename[MAX_LEN] ;

    char *cFileContent ;

    bool bEnde ;

 pWorkerParam = (struct WorkerParam *) pParam ;

 cCrLf[0] = 13 ; cCrLf[1] = 10 ; cCrLf[2] = 0 ;

    strcpy (c2CrLf, cCrLf) ; strcat (c2CrLf, cCrLf) ;

   

    bEnde = false ;

    strcpy (bufferRead,"") ;

    strcpy (tempRead, "") ;

 while (bEnde == false)

    {

        len = recv (pWorkerParam->Socket, tempRead,

                    sizeof(bufferRead), 0) ;

        strncat (bufferRead, tempRead, len) ;

        strcpy (tempRead, "") ;

        if (strstr (bufferRead, c2CrLf) != NULL)

            bEnde = true;

    }

    TRACE ("Request:\n%s",bufferRead) ;

    Sleep (5000);

 cli = (struct sockaddr_in *)&(pWorkerParam->Client);

 

    GetRequestFileName (bufferRead, cRelativeFilename,

                        pWorkerParam->DefaultFilename) ;

    GetFullFileName (cRelativeFilename, cAbsoluteFilename,

                     pWorkerParam->DocumentRoot) ;

    GetFileContent (cAbsoluteFilename, &cFileContent) ;

   

    memset (bufferWrite, 0, sizeof (bufferWrite)) ;

 strcpy (bufferWrite, cHeader) ;

    strcat (bufferWrite, cFileContent) ;

 len = strlen (bufferWrite) ;

    TRACE ("Response:\n%s",bufferWrite) ;

    send (pWorkerParam->Socket, bufferWrite, len, 0) ;

 closesocket (pWorkerParam->Socket) ;

    delete (cFileContent);

    delete (pWorkerParam) ;

    _endthread() ;

}

// Liefert den Dateinamen der Anfrage

int GetRequestFileName (char *buffer, char *cFilename,

                        char *cDefaultFilename)

{

    char cTemp[MAX_LEN] ;

    char *pPosLeerzeichen ;

    int nRet ;

    nRet = 0 ;

    // kamen mind. 4 Zeichen ?

    if (strlen (buffer) >= 4)

    {

        strncpy (cTemp, buffer, 4) ;

        cTemp [4] = '\0' ;

        // kam ein GET ?

        if (strcmp (cTemp, "GET ") == 0)

        {

            pPosLeerzeichen = strstr (buffer+4, " ") ;

            // haben wir ein folgendes Leerzeichen ?

            if (pPosLeerzeichen != NULL)

            {

                strncpy(cTemp, buffer+4, pPosLeerzeichen-buffer-4) ;

                cTemp[pPosLeerzeichen-buffer-4] = '\0' ;

                // ist es eine Datei oder in Verzeichnis ?

                if (cTemp[strlen(cTemp)-1] == '/')

                {

                    // ein Verzeichnis, dann kopieren wir die

                    // Defaultdatei hinten dran

                    strcat (cTemp, "index.html") ;

                }

                // nun haben wir den Dateinamen

                // relativ zum Wurzelverzeichnis

                strcpy (cFilename, cTemp) ;

            } // haben wir ein folgendes Leerzeichen ?

        } // kam ein GET ?

    } // kamen mind. 4 Zeichen ?

    return (nRet) ;

}

// Liefert den vollständigen Dateinamen

int GetFullFileName (char *cRelativeFilename,

                     char *cAbsoluteFilename, char *cDocumentRoot)

{

    int nRet ;

    nRet = 0 ;

    // hier kommen evtl. noch Aliases

    // die Doc-Root und den dateinamen zusammenkopieren

    strcpy (cAbsoluteFilename, cDocumentRoot) ;

    strcat (cAbsoluteFilename, cRelativeFilename) ;

    return (nRet) ;

}

 

// Liefert den Dateiinhalt

int GetFileContent (char *cAbsoluteFilename, char **cFileContent)

{

    int nRet ;

    long nFileLength ;

    FILE *datei ;

    long nPos ;

    char cZeile[MAX_LEN] ;

    char *pPos ;

    nRet = 0 ;

    *cFileContent = new (char[32768]) ;

    strcpy (*cFileContent, "") ;

    pPos = strstr (cAbsoluteFilename, "/") ;

    while (pPos != NULL)

    {

        *pPos = '\\' ;

        pPos = strstr (cAbsoluteFilename, "/") ;

    }

    datei = fopen (cAbsoluteFilename, "rt") ;

    if (datei != NULL)

    {

        nPos = 0 ;

        if (!feof (datei))

        {

            while (fgets (cZeile, MAX_LEN, datei) != NULL)

            {

                strcat (*cFileContent, cZeile) ;

                strcpy (cZeile, "") ;

            }

        }

        fclose (datei) ;

    }

    return (nRet) ;

}

 



Last update:  13.07.2005