Einfacher HTTP Server, sendet keine Daten



  • Ich habe aus dem Buch Visual C++.NET, das Beispiel für einen kleinen HTTP-Server
    abgetippt, es kompiliert ohne Probleme, aber der Server kann keine Daten senden,
    auch die Version von der CD, sendet keine Daten, beim Aufruf über 'localhost' im
    Browser.
    Mein Webserver (Apache), funktioniert beim Aufruf, über den localhost, denke es
    liegt daher wohl bei der Implementierung ein Fehler vor.

    Das Programm leitet 2Klassen von CAsyncSocket ab, einmal die CListenSocket und
    die CRequestSocket.
    Die Klasse CListenSocket erstellt ein Objekt von CRequestSocket, in der
    überschriebenen Methode OnAccept.
    Die Klasse CRequestObjekt empfängt, dann die Daten des Clients und sendet einen
    Header + ein einfaches "Hallo Welt", egal was der Client sendet.

    Der Socket wird erstellt in der InitInstance () der Anwendungsklasse, dort wird
    nach den Zeilen

    CWinApp::InitInstance();
    
    	if (!AfxSocketInit())
    	{
    		AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
    		return FALSE;
    	}
    

    Die Methode StartListening () aufgerufen, welche einen neuen Socket auf Port 80
    erstellt.
    StartListening und StopListening

    void CIsrvBSPApp::StartListening(void)
    {
    	StopListening ();
    
    	m_pListen = new CListenSocket ();
    	if (m_pListen) {
    		if (m_pListen->Create (80, SOCK_STREAM, FD_ACCEPT))
    			m_pListen->Listen ();
    	}
    }
    
    void CIsrvBSPApp::StopListening(void)
    {
    	if (m_pListen) {
    		m_pListen->Close ();
    		delete m_pListen;
    		m_pListen = NULL;
    	}
    }
    

    StopListening wird beim beenden des Programmes aufgerufen.

    Die Klasse CListenSocket:

    //Header
    #pragma once
    #include "stdafx.h"
    #include "RequestSocket.h"
    
    class CListenSocket :
    	public CAsyncSocket
    {
    public:
    	CListenSocket(void);
    	virtual void OnAccept (int nErrorCode);
    	~CListenSocket(void);
    };
    
    //Implementierungsdatei
    #include "StdAfx.h"
    #include ".\listensocket.h"
    
    CListenSocket::CListenSocket(void)
    {
    }
    
    CListenSocket::~CListenSocket(void)
    {
    }
    
    void CListenSocket::OnAccept (int nErrorCode) {
    
    	CRequestSocket *pRequest = new CRequestSocket ();
    	if (Accept (*pRequest)) {
    		pRequest->AsyncSelect (FD_READ | FD_CLOSE);
    	}
    }
    

    Die Klasse CRequestSocket

    //Header
    #pragma once
    #include "afxsock.h"
    #include <cstring>
    
    const int m_BufSize = 1024;
    const char m_header[] = "HTTP/1.0 200 OK\r\n"
    "Server: Mein erster Server\r\n"
    "Date: Mon, 24 Oktober 2001 12:00:00 GTM\r\n"
    "Content-Type: text/html\r\n"
    "Accept-Ranges: bytes\r\n"
    "Content-Length: 10\r\n"
    "\r\n";
    class CRequestSocket :
    	public CAsyncSocket
    {
    public:
    	CRequestSocket(void);
    	~CRequestSocket(void);
    
    	virtual void OnReceive (int nErrorCode);
    	virtual void OnSend (int nErrorCode);
    private:
    
    	char m_buffer[m_BufSize];
    };
    
    //Implementierungsdatei
    #include "StdAfx.h"
    #include ".\requestsocket.h"
    
    CRequestSocket::CRequestSocket(void)
    {
    }
    
    CRequestSocket::~CRequestSocket(void)
    {
    }
    
    void CRequestSocket::OnReceive (int nErrorCode)
    {
    	Receive (m_buffer, m_BufSize);
    
    	std::strcpy (m_buffer, m_header);
    	std::strcpy (m_buffer+strlen (m_header), "Hallo Welt");
    	AsyncSelect (FD_WRITE | FD_CLOSE);
    }
    
    void CRequestSocket::OnSend (int nErrorCode)
    {
    	Send (m_buffer, std::strlen (m_header + std::strlen ("Hallo Welt")));
    	ShutDown (both);
    	delete this;
    }
    

    Nun die Frage, weshalb wird nichts versendet?

    Danke für eure Mühe 🙂



  • hallo

    habe vor jahren einen ähnlichen server gebastelt.. sieht gut aus..

    schau mal, ob du dir ein wenig mit messageboxen einige sachen ausgeben kannst, zum fehlersuchen..

    erweitere die onAccept mal um das ausgeben der ip des rechners, der angefragt hat, dann weißt du, ob du "gehört" wirst..

    er gibt dir die auflösung von localhost, die 127.0.0.1

    void CListenSocket::OnAccept(int nErrorCode)
    {
    	CRequestSocket* pRequest=new CRequestSocket;
    	if (Accept (*pRequest)){
    
    		//bekomme die Ip des verbundenen Computers
    		CString PeerAddress;
    		UINT PeerPort=0;
    		pRequest->GetPeerName(PeerAddress,PeerPort );
    
    		//ist diese Messagebox aktiviert, die eingehende IpNummer des anfragenden
    		//Computers eingesehen werden
    		AfxMessageBox (PeerAddress);
    
    ....
    .....
    ....
    

    das gleiche würde ich auch in onSend und onReceive versuchen... also mit den messageboxen mal schaun, ob die daten wirklich im buffer sind und gesendet werden..

    bis hierhin erstmal...



  • In der MessageBox aus OnAccept steht "127.0.0.1", also wird richtig aufgelöst
    und die MessageBox poppt auf sobald ich die Anfrage über den Browser losschicke.

    Habe die Funktion OnReceive wie folgt geändert:

    void CRequestSocket::OnReceive (int nErrorCode)
    {
    	Receive (m_buffer, m_BufSize);
    
    	CString rec (m_buffer); // <---
    	AfxMessageBox (rec); // <----
    
    	std::strcpy (m_buffer, m_header);
    	std::strcpy (m_buffer+strlen (m_header), "Hallo Welt");
    	AsyncSelect (FD_WRITE | FD_CLOSE);
    }
    

    Die MessageBox, gibt folgendes aus: http://www.programminghints.de/http_server/receive.jpg

    Dann habe ich die Funktion OnReceive wie folgt geändert:

    void CRequestSocket::OnReceive (int nErrorCode)
    {
    	Receive (m_buffer, m_BufSize);
    
    	CString rec (m_buffer);
    	AfxMessageBox (rec);
    
    	std::strcpy (m_buffer, m_header);
    	std::strcpy (m_buffer+strlen (m_header), "Hallo Welt");
    	rec = m_buffer; // <-----
    	AfxMessageBox (rec); // <-----
    	AsyncSelect (FD_WRITE | FD_CLOSE);
    }
    

    Die MessageBox gibt folgendes aus: http://www.programminghints.de/http_server/receive2.jpg

    Die Daten in OnSend sind die gleichen wie auf dem Bild http://www.programminghints.de/http_server/receive2.jpg
    zu sehen ist.

    Also die Daten stimmen.



  • Hallo,

    SirLant schrieb:

    Die Daten in OnSend sind die gleichen wie auf dem Bild http://www.programminghints.de/http_server/receive2.jpg
    zu sehen ist.

    wo hast du das überprüft? Bis zu dieser Zeile:

    Send (m_buffer, std::strlen (m_header + std::strlen ("Hallo Welt")));
    

    mag der Wert in m_buffer ja noch stimmen, aber durch diese (für mich etwas unverständliche) Berechnung der Puffer-Länge:

    std::strlen (m_header + std::strlen ("Hallo Welt"))

    der zu sendenden Daten wird dafür gesorgt, daß gerade der Content, nämlich der "Hallo Welt"-Text, nicht mitgesendet wird... 😕 , also irgendwie seltsam der Quell-Text...richtig(er) wäre m.E. das hier:

    Send (m_buffer, std::strlen (m_header) + std::strlen ("Hallo Welt"));
    

    da du in deiner Eingangsfrage von "Abtippen" gesprochen hast: vielleicht ein (Ab-)Tippfehler, aber das fällt wohl weg, wenn auch die CD-Version nicht läuft.

    Probier's mal, ansonsten ist eine Fehlerbehandlung fällig (in OnSend kommt der Server ja, wenn ich dich richtig verstanden habe, dann Überprüfen des Rückgabe-Wertes von Send, anschließendes GetLastError, das übliche eben...)

    MfG



  • Ok das mit strlen macht für mich jetzt wo du es erwähnst ebenfalls keinen Sinn,
    ich werd mal deine alternative Version testen, welche sicher zu dem richtigen
    Ergebnis führt 🙂

    Edit:

    Jetzt geht es 🙂


Anmelden zum Antworten