Webserver programmieren... Problem mit recv()
-
Da steht "waits for data to arrive" und nicht "waits for all data to arrive"
-
For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much data as is currently available—up to the size of the buffer specified.
-
jo, wenn recv() blockiert ist schlicht und ergreifend gerade nix da

Im Prinzip musst du recv() solange immer wieder aufrufen und die Daten in einen Buffer pappen bis zwei Zeilenumbrüche hintereinander kommen, dann ist der HTTP-Header vorbei. Bei POST z.B. könnten dann halt noch Daten nach dem HTTP-Header kommen.
-
Danke! Ich habe dieses Problem gelöst

Ich habe aber noch eine Frage, denn ich würde gerne Umgebungsvariablen für meinen Webserver erstellen: GATEWAY_INTERFACE, SCRIPT_NAME, REMOTE_ADDR, usw...
Wie richte ich diese Umgebungsvariablen ein? Das würde mir wirklich sehr weiterhelfen

Abfragen kann ich diese dann so weit ich das feststellen konnte mit getenv()

Vielen Dank im Voraus,
HilfeNoetig
-
"für" deinen Webserver? - Erzeugt der Webserver nicht normalerweise diese Variablen für CGI-Programme?
An CGI-Programme kannst du die direkt wenn du das CGI-Programm mittels CreateProcess() startest übergeben und über die LpStartupInfo auch direkt die Ausgabe umleiten.
-
Hallo geeky,
vielen Dank für deine Hilfe

Ich dachte ich setze einfach die Umgebungsvariablen und "vererbe" diese dann an das CGI Programm
Ich habe jedoch ein neues Problem:
Ich möchte jetzt ein Programm starten(CreateProcess) und eine Zeile in die Eingabe des Programms schreiben und danach die Ausgabe des Programms auslesen. Jedoch verzweifel ich daran gerade
Ich habe schon hier im Forum gesucht, jedoch waren die meisten der Frage unbeantwortet.Hat hier also jemand ein Beispiel dafür? Ich weiß nicht, ob man unbedingt mit CreatePipe arbeiten muss? Vielleicht gehts auch ganz anders
Wäre über Hilfe wirklich sehr dankbar!!!#define BUFSIZE 1024 STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa; HANDLE hPipeRead,hPipeWrite; char cPipeResult[BUFSIZE]; DWORD dwBytes; // // Erstellen der Pipe sa.nLength=sizeof(sa); sa.bInheritHandle=TRUE; sa.lpSecurityDescriptor=NULL; CreatePipe(&hPipeRead,&hPipeWrite, &sa, 0); si.cb=sizeof(STARTUPINFO); si.lpReserved=NULL; si.lpDesktop=NULL; si.lpTitle=NULL; si.dwX=0; si.dwY=0; si.dwXSize=640; si.dwYSize=400; si.dwXCountChars=0; si.dwYCountChars=0; si.dwFillAttribute=FOREGROUND_BLUE; si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; si.wShowWindow=SW_HIDE; si.cbReserved2=0; si.lpReserved2=NULL; si.hStdInput=GetStdHandle(STD_INPUT_HANDLE); si.hStdOutput=hPipeWrite; si.hStdError=GetStdHandle(STD_ERROR_HANDLE); //STARTUPINFO si; //PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); if( !CreateProcess( NULL, // No module name (use command line) "test.cgi", // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable true, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { printf( "CreateProcess failed (%d)\n", GetLastError() ); } memset(cPipeResult,0,BUFSIZE); //WriteFile( // ? ReadFile(hPipeRead,cPipeResult,sizeof(cPipeResult),&dwBytes,NULL); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); /* Nebenbei scheint irgendeine Funktion das Programm zu "blocken"... */Vielen Dank im Voraus,
HilfeNoetig
-
push...
-
Ich kenn mich mit Pipes leider nicht aus

Macht das nicht evtl. Sinn erst auf Prozessende zu warten (WaitForSingleObject) und erst dann aus der Pipe zu lesen?
Wo blockiert er denn?
-
Es ist nicht gerade ratsam das Redirect auf unterschieldiche Streams laufen zu lassen (also den STD und ERR-Stream).
Das führt meistens zu Problemen...
Wenn Du STD und ERR getrennt haben, willst, kommst Du um einem eigenen Thread nicht drum rum, da Du *beide* Streams lesen musst sonst blokiert Deine Ausgabe!Und damit Du gleich siehst, dass das was Du gemacht hast etwas zu einfach gestrickt ist:
http://support.microsoft.com/kb/190351/en-usFazit: Unter 300 Zeilen kommst Du kaum aus

-
Vielen Dank für die Antworten

Ich habe noch sehr viel rumprobiert und bin schon weiter gekommen, denn das CGI-Programm wird korrekt ausgeführt. Ich dachte also ich hatte es endlich geschafft und drückte begeistert immer wieder auf die Aktualiseren Taste(F5) meines Browser um zu überprüfen, ob die Ausgabe sich auch nicht (durch Programmierfehler) veränderte. Die Ausgabe veränderte sich auch nicht, aber nach einigen malen blieb alles stehen(Browser lädt sich tot). Mein Programm stand still... Ein Reproduzieren des Fehlers war ohne Probleme möglich.
Ich war und bin noch immer ziemlich enttäuscht
Vielleicht brauche ich gar keine Pipe? Kann doch alles nicht soooooo schwer sein...
Aktueller Code:
void execCGI(const char *file, const char *para, SOCKET sock) { printf("execCGI\n\n"); HANDLE readHandle; HANDLE writeHandle; DWORD dwWaitResult = WAIT_TIMEOUT, dwBytesRead, dwBytesWrote, dwSizeLow, dwSizeHigh, dwError; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; STARTUPINFO si; ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES)); ZeroMemory(&pi,sizeof(PROCESS_INFORMATION)); ZeroMemory(&si,sizeof(STARTUPINFO)); sa.bInheritHandle=true; sa.lpSecurityDescriptor=NULL; sa.nLength=sizeof(SECURITY_ATTRIBUTES); si.cb=sizeof(STARTUPINFO); si.dwFlags=STARTF_USESHOWWINDOW; si.wShowWindow=SW_HIDE; if (!CreatePipe(&readHandle,&writeHandle,&sa,NULL)) { OutputDebugString("cmd: CreatePipe failed!\n"); } SetStdHandle(STD_OUTPUT_HANDLE,writeHandle); SetStdHandle(STD_INPUT_HANDLE,readHandle); if (!CreateProcess(NULL,const_cast<char *>(file),NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)) { OutputDebugString("cmd: CreateProcess failed!\n"); } char temp[256]; sprintf(temp, "%s\n", para); // Parameter für das CGI WriteFile(writeHandle, temp, strlen(temp), &dwBytesWrote, 0); const int MAX_LINE_LENGTH = 1024; char cReadLine[MAX_LINE_LENGTH]; char header[256]; sprintf(header, "HTTP/1.1 200 OK\r\nServer: HTTP-Test\r\n"); // Header für den Browser send(sock, header, (int) strlen(header), 0); while(dwWaitResult != WAIT_OBJECT_0) { printf("1 |-"); dwWaitResult = WaitForSingleObject(pi.hProcess, 10); // Eventuell blockt es hier! printf("-|\n"); while(dwSizeLow = GetFileSize(readHandle, &dwSizeHigh)) { printf("2 |-"); ZeroMemory(cReadLine, MAX_LINE_LENGTH); printf("-|\n"); printf("3 |-"); if(ReadFile(readHandle, cReadLine, MAX_LINE_LENGTH - 1, &dwBytesRead, NULL)) { // Eventuell blockt es hier! if(dwBytesRead) { send(sock, cReadLine, (int) strlen(cReadLine), 0); } } else { dwError = GetLastError(); } printf("-|\n"); } } Sleep(100); if (!CloseHandle(readHandle)) { OutputDebugString("cmd: CloseHandle(readHandle) failed!\n"); } if (!CloseHandle(writeHandle)) { OutputDebugString("cmd: CloseHandle(writeHandle) failed!\n"); } }Vielen dank im Voraus!
HilfeNoetig
-
Du hast den Error-Handle vergessen...
-
Hast du einen Vorschlag, wie ich das am Besten einbaue? Würde mir sehr helfen!
Danke
-
Siehe KB-Artikel?