Zum Inhalt springen

C Builder und Socket Programmierung - für die harten Jungs :-)


paule22

Empfohlene Beiträge

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ß .....

Link zu diesem Kommentar
Auf anderen Seiten teilen

// ----------------------------------------------------------------------------

// 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 ....

Link zu diesem Kommentar
Auf anderen Seiten teilen

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;

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...