paule22 Geschrieben 29. Mai 2002 Teilen Geschrieben 29. Mai 2002 Hallo Leute, heute mal ein Problem der Socket Programmierung: Ich habe ein ServerProgram, das auf Port hört. Wenn es gestartet wird und man im Explorer folgendes eingibt: http:/127.0.0.1 , dann wird ein Simpler Text ausgegeben - aber jetzt kommt das Problem, nachdem der Text ausgegeben ist, schließe ich das Client-Socket und siehe da, der Browser zeigt mir nun völlig andere Daten an - "Seite kann nicht angezeigt werden " ist doch blöde oder ??? okay hier der Code dazu PS: Wer den Fehler findet bekommt vielleicht ne Belohnung :-D ------------------------------------- // ---------------------------------------------------------------------------- #pragma warn -8060 #pragma warn -8071 #pragma warn -8080 #pragma warn -8084 #include <stdio.h> #include <io.h> #include <iostream> #include <string.h> #include <process.h> #include <windows.h> #include <winsock2.h> #include "start.h" #pragma hdrstop AnsiString HTTPD_ROOT; AnsiString DOCUMENT_LOCATION; const int DYNAMIC_MODULE_LIMIT = 64; // ---------------------------------------------------------------------------- // Port number for server running standalone ... // ---------------------------------------------------------------------------- const int DEFAULT_HTTP_PORT = 80; const int DEFAULT_HTTPS_PORT = 443; // ---------------------------------------------------------------------------- // The name of the log files ... // ---------------------------------------------------------------------------- AnsiString DEFAULT_XFERLOG; AnsiString DEFAULT_ERRORLOG; AnsiString DEFAULT_PIDLOG; AnsiString DEFAULT_SCOREBOARD; AnsiString DEFAULT_LOCKFILE; AnsiString DEFAULT_INDEX; SOCKET ListeningSocket; SOCKET NewConnection; SOCKADDR_IN ServerAddr; SOCKADDR_IN ClientAddr; int ClientAddrLen; DWORD gdwListenThread; HANDLE ghExit; unsigned __stdcall ListenThread(void *pVoid); // ---------------------------------------------------------------------------- // implementation of the exception class constructors... // ---------------------------------------------------------------------------- __fastcall TApacheException::TApacheException(AnsiString text) { ErrorText = text; } __fastcall TApacheException::TApacheException(int code) { ErrorCode = code; } //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" Tapache_form *apache_form; //--------------------------------------------------------------------------- __fastcall Tapache_form::Tapache_form(TComponent* Owner) : TForm(Owner) { } void __fastcall Tapache_form::Button1Click(TObject *Sender) { WSACleanup(); } //--------------------------------------------------------------------------- void __fastcall Tapache_form::FormShow(TObject *Sender) { server_main(); } //--------------------------------------------------------------------------- void __fastcall Tapache_form::socket_init(void) { int version = MAKEWORD(2,2); WSADATA wsd; int err; err = WSAStartup((WORD)version, &wsd); if (err) { AnsiString str = "WSAStartup failed: "; str += IntToStr(WSAGetLastError()); throw TApacheException(str); } if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2) throw TApacheException("Apache requieres Winsock 2. Please read the FAQ for more informations,"); } void __fastcall Tapache_form::server_main(void) { // ---------------------------------- // first, tackle the default path ... // ---------------------------------- AnsiString str = Application->ExeName; int i, pos = 1; for (i = 1; i < str.Length(); i++) { if (str[str.Length()-i] == '\\') break; pos++; } str.Delete(str.Length()-pos-1,pos+1); str = AnsiLowerCase(str); HTTPD_ROOT = str; DOCUMENT_LOCATION = HTTPD_ROOT + "\\htdocs"; // -------------------------------- // define the default log files ... // -------------------------------- DEFAULT_XFERLOG = HTTPD_ROOT + "\\logs\\access.log"; DEFAULT_ERRORLOG = HTTPD_ROOT + "\\logs\\error.log"; DEFAULT_PIDLOG = HTTPD_ROOT + "\\logs\\httpd.pid"; DEFAULT_SCOREBOARD = HTTPD_ROOT + "\\logs\\apache_runtime_status"; DEFAULT_LOCKFILE = HTTPD_ROOT + "\\logs\\accept.lock"; DEFAULT_INDEX = "index.html"; try { // ----------------------------- // Initialize the stupid sockets // ----------------------------- output->Lines->Add("initializiere sockets ..."); socket_init(); // --------------------------------------- // Create the exit signal event object ... // --------------------------------------- ghExit = CreateEvent(NULL, // Security TRUE, // Manual reset FALSE, // Initial State NULL); // Name int Port = 80; //3456; if ((ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { AnsiString str = "socket failed with error: "; str += IntToStr(WSAGetLastError()); throw TApacheException(str); } ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(Port); ServerAddr.sin_addr.s_addr = INADDR_ANY; if (bind(ListeningSocket, (LPSOCKADDR)&ServerAddr, sizeof(struct sockaddr)) == SOCKET_ERROR) { AnsiString str = "bind failed with error: "; str += IntToStr(WSAGetLastError()); closesocket(ListeningSocket); throw TApacheException(str); } if (listen(ListeningSocket, SOMAXCONN) == SOCKET_ERROR) { AnsiString str = "listen failed with error: "; str += IntToStr(WSAGetLastError()); closesocket(ListeningSocket); throw TApacheException(str); } output->Lines->Add("We are awaiting a connection on port: 3456"); // ------------------------------- // create the listening thread ... // ------------------------------- unsigned int ThreadAddr; gdwListenThread = ::_beginthreadex( NULL, // Security 0, // Stack size ListenThread, // Function address &ghExit, // Argument 0, // Init flag &ThreadAddr); // Thread address if (!gdwListenThread) { AnsiString str = "Could not create listening thread: "; str += IntToStr(GetLastError()); closesocket(ListeningSocket); throw TApacheException(str); } output->Lines->Add("apache running ..."); } catch (TApacheException ev) { closesocket(ListeningSocket); WSACleanup(); output->Lines->Add(ev.ErrorText); } Label1->Caption = DOCUMENT_LOCATION; return; } der rest folgt im anschluß ..... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 29. Mai 2002 Autor Teilen Geschrieben 29. Mai 2002 // ---------------------------------------------------------------------------- // tracks the number of active client threads ... // ---------------------------------------------------------------------------- DWORD gdwClientCount = 0; CRITICAL_SECTION gcriticalClients; HANDLE ghNoClients; HANDLE InitClientCount(void) { gdwClientCount = 0; InitializeCriticalSection(&gcriticalClients); // ------------------------------------------- // Create the "no clients" signal event object // ------------------------------------------- ghNoClients = CreateEvent(NULL, // Security TRUE, // Manual reset TRUE, // Initial State NULL); // Name return ghNoClients; } void IncrementClientCount(void) { EnterCriticalSection(&gcriticalClients); gdwClientCount++; LeaveCriticalSection(&gcriticalClients); ResetEvent(ghNoClients); } void DecrementClientCount(void) { EnterCriticalSection(&gcriticalClients); if (gdwClientCount > 0) gdwClientCount--; LeaveCriticalSection(&gcriticalClients); if (gdwClientCount < 1) SetEvent(ghNoClients); } void DeleteClientCount(void) { DeleteCriticalSection(&gcriticalClients); CloseHandle(ghNoClients); } void CloseConnection(LPREQUEST lpReq) { HTTPSTATS stats; int nRet; // ---------------------------------- // Log the event and close the socket // ---------------------------------- AnsiString str = "1) CloseConnection(): Closing socket: "; str += IntToStr(lpReq->Socket); apache_form->output->Lines->Add(str); nRet = closesocket(lpReq->Socket); if (nRet == SOCKET_ERROR) { str = "closesocket(): "; str += IntToStr(WSAGetLastError()); apache_form->output->Lines->Add(str); } } bool SendBuffer(LPREQUEST lpReq, char *pBuf, DWORD dwBufSize) { WSABUF wsabuf; WSAOVERLAPPED over; DWORD dwRecv; DWORD dwFlags; DWORD dwRet; HANDLE hEvents[2]; bool fPending; int nRet; // --------------------------------------------- // Setup the WSABUF and WSAOVERLAPPED structures // --------------------------------------------- wsabuf.buf = pBuf; wsabuf.len = dwBufSize; over.hEvent = WSACreateEvent(); fPending = FALSE; nRet = WSASend(lpReq->Socket, // Socket &wsabuf, // WSABUF 1, // Number of buffers &dwRecv, // Bytes received 0, // Flags NULL, //&over, // WSAOVERLAPPED NULL); // Completion function if (nRet != 0) { if (WSAGetLastError() == WSA_IO_PENDING) fPending = TRUE; else { AnsiString str = "--> WSASend(): "; str += IntToStr(WSAGetLastError()); apache_form->output->Lines->Add(str); CloseHandle((HANDLE)over.hEvent); return false; } } // ---------------------------- // If the I/O isn't finished... // ---------------------------- if (fPending) { // -------------------------------- // Wait for the request to complete // or the exit event to be signaled // -------------------------------- hEvents[0] = (HANDLE) over.hEvent; hEvents[1] = lpReq->hExit; dwRet = WaitForMultipleObjects(2, hEvents, false, INFINITE); // ---------------------------- // Was the recv event signaled? // ---------------------------- if (dwRet != 0) { CloseHandle((HANDLE) over.hEvent); return false; } // -------------- // Get I/O result // -------------- if (!WSAGetOverlappedResult(lpReq->Socket, &over, &dwRecv, false, &dwFlags)) { AnsiString str = "WSAGetOverlappedResult(): "; str += IntToStr(WSAGetLastError()); apache_form->output->Lines->Add(str); CloseHandle((HANDLE)over.hEvent); return false; } } CloseHandle((HANDLE)over.hEvent); return true; } weiter im im anschluss .... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 29. Mai 2002 Autor Teilen Geschrieben 29. Mai 2002 void SendError(LPREQUEST lpReq, int uError) { static char szMsg[512]; static char *szStatMsgs [] = { "200 OK", "201 Created", "202 Accepted", "204 No Content", "301 Moved Permanently", "302 Moved Temporarily", "304 Not Modified", "400 Bad Request", "401 Unauthorized", "403 Forbidden", "404 Not Found", "500 Internal Server Error", "501 Not Implemented", "502 Bad Gateway", "503 Service Unavailable" }; #define NUMSTATMSGS sizeof(szStatMsgs) / sizeof(szStatMsgs[0]) if (uError < 0) return; wsprintf(szMsg, "<html><body><h1>%s</h1></body></html>",szStatMsgs[uError]); int rr = send(lpReq->Socket,szMsg,strlen(szMsg),0); AnsiString str = "sending string(): "; str += IntToStr(WSAGetLastError()); str += ",,, "; str += rr; apache_form->output->Lines->Add(str); } bool RecvRequest(LPREQUEST lpReq, char *pBuf, int dwBufSize) { WSABUF wsabuf; WSAOVERLAPPED over; DWORD dwRecv; DWORD dwFlags; DWORD dwRet; HANDLE hEvents[2]; bool fPending; int nRet; // ---------------------------------------------- // Zero the buffer so the recv is null-terminated // ---------------------------------------------- memset(pBuf, 0, dwBufSize); // --------------------------------------------- // Setup the WSABUF and WSAOVERLAPPED structures // --------------------------------------------- wsabuf.buf = pBuf; wsabuf.len = dwBufSize; over.hEvent = WSACreateEvent(); dwFlags = MSG_PEEK; fPending = false; nRet = WSARecv(lpReq->Socket, // Socket &wsabuf, // WSABUF 1, // Number of buffers &dwRecv, // Bytes received &dwFlags, // Flags NULL, // WSAOVERLAPPED NULL); // Completion function if (nRet != 0) { if (WSAGetLastError() != WSA_IO_PENDING) { AnsiString str = "W SARecv(): "; str += IntToStr(WSAGetLastError()); apache_form->output->Lines->Add(str); CloseHandle((HANDLE)over.hEvent); return false; } else fPending = true; } apache_form->output->Lines->Add("fPending = TRUE"); // ---------------------------- // If the I/O isn't finished... // ---------------------------- if (fPending) { // -------------------------------------------------- // Wait for the request to complete or the exit event // -------------------------------------------------- hEvents[0] = (HANDLE)over.hEvent; hEvents[1] = lpReq->hExit; dwRet = WaitForMultipleObjects(2, hEvents, false, INFINITE); // ---------------------------- // Was the recv event signaled? // ---------------------------- if (dwRet != 0) { apache_form->output->Lines->Add("dwRet in RecvRequest()"); CloseHandle((HANDLE)over.hEvent); return false; } if (!WSAGetOverlappedResult(lpReq->Socket, &over, &dwRecv, false, &dwFlags)) apache_form->output->Lines->Add("WSAGetOverlappedResult() in RecvRequest()"); CloseHandle((HANDLE)over.hEvent); return false; } apache_form->output->Lines->Add("complete recv"); // ----------------------------------------- // Recv event is complete -- keep statistics // ----------------------------------------- lpReq->dwRecv += dwRecv; CloseHandle((HANDLE)over.hEvent); return true; } int ParseRequest(LPREQUEST lpReq, char *lpBuf) { char szSeps[] = " \n"; char *cpToken; // ------------------------------------------ // Don't let requests include ".." characters // in requests // ------------------------------------------ if (strstr(lpBuf, "..") != NULL) { // Send "bad request" error return(HTTP_STATUS_BADREQUEST); } // // Determine request method // cpToken = strtok(lpBuf, szSeps); if (!stricmp(cpToken, "GET")) lpReq->nMethod = METHOD_GET; else { // Send "not implemented" error return(HTTP_STATUS_NOTIMPLEMENTED); } // // Get the file name // cpToken = strtok(NULL, szSeps); if (cpToken == NULL) { // Send "bad request" error return(HTTP_STATUS_BADREQUEST); } // strcpy(lpReq->szFileName, szWebRoot); // if (strlen(cpToken) > 1) // strcat(lpReq->szFileName, cpToken); // else strcat(lpReq->szFileName, "/index.html"); return 0; } unsigned __stdcall ClientThread(void *pVoid) { int nRet; char buf[1024]; LPREQUEST lpReq = (LPREQUEST)pVoid; // ----------------- // Count this client // ----------------- IncrementClientCount(); // --------------------- // Recv the request data // --------------------- if (RecvRequest(lpReq, buf, 1024) == false) { AnsiString str = "RecvRequest(): close___: "; str += lpReq->Socket; apache_form->output->Lines->Add(str); CloseConnection(lpReq); delete lpReq; DecrementClientCount(); return 0; } // ---------------------- // Parse the request info // ---------------------- nRet = ParseRequest(lpReq, buf); if (nRet) { apache_form->output->Lines->Add("ParseRequest(): nret"); SendError(lpReq, nRet); CloseConnection(lpReq); free(lpReq); DecrementClientCount(); return 0; } // char dwON = '1'; DWORD dwON = 1; setsockopt(lpReq->Socket,IPPROTO_TCP, SO_DONTLINGER, (char*)&dwON,sizeof(DWORD)); if (SendBuffer(lpReq,"<html><head><title>AddA</title></head><body><h1><b>Hello World !</b></h1></body></html>", 1024) == false) apache_form->output->Lines->Add("can't sending www.de"); else apache_form->output->Lines->Add("sending to www.de"); Sleep((DWORD) 2000); // ------------ // Clean up ... // ------------ apache_form->output->Lines->Add("clean up connection"); // here, if I close the connection, the first sending // data will disappear and the browser sent me new data // "site can not display" ... // I don't know why ! // any ideas ??? CloseConnection(lpReq); delete pVoid; // -------------------- // Subtract this client // -------------------- DecrementClientCount(); return 0; } unsigned __stdcall ListenThread(void *pVoid) { SOCKET socketClient; unsigned ThreadAddr; DWORD dwClientThread; SOCKADDR_IN SockAddr; LPREQUEST lpReq; int nLen; DWORD dwRet; HANDLE hNoClients; LPHANDLE pHandle = (LPHANDLE)pVoid; // ----------------------------------- // Initialize client thread count to 0 // ----------------------------------- hNoClients = InitClientCount(); // ---------------------------------- // Loop forever accepting connections // ---------------------------------- while(1) { // ------------------ // Block on accept() // ------------------ nLen = sizeof(SOCKADDR_IN); socketClient = accept(ListeningSocket,(LPSOCKADDR)&SockAddr,&nLen); if (socketClient == INVALID_SOCKET) { apache_form->output->Lines->Add("ListenThread(): INVALID_SOCKET"); break; } // --------------------- // We have a connection // --------------------- AnsiString str = "Connection accepted on socket: "; str += IntToStr(socketClient); str += " from: "; str += inet_ntoa(SockAddr.sin_addr); apache_form->output->Lines->Add(str); // ---------------------------------------------- // Allocate parms for client and fill in defaults // ---------------------------------------------- lpReq = new REQUEST[sizeof(REQUEST)]; if (!lpReq) { apache_form->output->Lines->Add("No memory for client request !"); continue; } lpReq->hExit = *pHandle; lpReq->Socket = socketClient; lpReq->dwConnectTime = ::GetTickCount(); lpReq->hFile = INVALID_HANDLE_VALUE; lpReq->dwRecv = 0;; lpReq->dwSend = 0; DWORD dwON = 1; setsockopt(lpReq->Socket,IPPROTO_TCP, SO_DONTLINGER, (char*)&dwON,sizeof(DWORD)); // -------------------------------------------- // Start a client thread to handle this request // -------------------------------------------- dwClientThread = _beginthreadex( NULL, // Security 0, // Stack size ClientThread, // Thread function lpReq, // Argument 0, // Init flag &ThreadAddr); // Thread address if (!dwClientThread) apache_form->output->Lines->Add("Couldn't start client thread"); // ---------------------------------------- // We won't be using client thread handles, // so we close them when they are created. // The thread will continue to execute. // ---------------------------------------- CloseHandle((HANDLE)dwClientThread); } // ------------------- // Wait for exit event // ------------------- WaitForSingleObject((HANDLE)*pHandle, INFINITE); // // Wait for ALL clients to exit // dwRet = WaitForSingleObject(hNoClients, 5000); if (dwRet == WAIT_TIMEOUT) { apache_form->output->Lines->Add("One or more client threads did not exit"); } DeleteClientCount(); return 0; } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 29. Mai 2002 Autor Teilen Geschrieben 29. Mai 2002 so das wars, hoffe jemand kann helfen paul Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.