|
Verfasser |
Nachricht |
Gigor
Durchstarter
Beiträge: 72
Gruppe: User
Registriert seit: Jun 2011
Status:
Offline
Danke erhalten: 18
|
Problem mit Threads
Hi,
bin gerade dabei in C einen miniHTTP Server zu basteln, und soweit sogut er liefert auch schon erste Testseiten aus
Ich hab es, der einfach halt halber, so gemacht, dass für jede datei eine neue Verbindung und ein neuer Thread gestartet wird.
Soweit funktioniert das auch, nur nach kurzer Zeit hängt es sich bei der Funktion sceKernelStartThread auf, freezt und schaltet sich schließlich auf selbst aus (unsanft, wie wenn man en Akku rausmacht..)
Weiß jemand woran es liegen könnte, wie man es behebt oder umgeht (also einen Fehler frühzeitg erkennen?)
void klientThreadStarten(int socket){
char name[32];
sprintf(name,"Client%d",gesamtAnfragen);
SceUID thid = sceKernelCreateThread(name,klientBedienen,0x18,0x10000,0,NUL L); //Zahlenwerte von dem Beispiel in der Dokumentation
printf("Starte Thread %s : %d...",name,thid);
//Hier hängt sichs auf:
int tRueck = sceKernelStartThread(thid,sizeof(socket),&socket);
printf("Thread %s gestartet: %d\n",name,tRueck);
}
Danke schonmal
Gigor
Dieser Beitrag wurde zuletzt bearbeitet: 13.01.2012 18:13 von Gigor.
|
|
13.01.2012 18:13 |
|
|
|
vista200
Head of Awesomeness
Beiträge: 189
Gruppe: User
Registriert seit: Jul 2009
Status:
Offline
Danke erhalten: 139
|
RE: Problem mit Threads
Der RAM der PSP ist voll. Oder der zugewiesene Speicher des gesamten Programms. Je nachdem, was zuerst eintrifft
Ich glaube auch, dass 65536 Byte für eine Anfrage vielleicht etwas zu viel sind. Reichen nicht 4096 Byte (0x1000) aus?
Das Problem ist, dass, wenn ein Thread erstellt werden soll und dieser mehr RAM beansprucht, als verfügbar ist, dann liefert sceKernelCreateThread einen negativen Wert zurück.
Dieser negative Wert ist entsprechend die Fehlermeldung und lässt sich in der Dokumentation nachschlagen.
Du solltest daher überprüfen, ob thid größer als null ist und erst dann sceKernelStartThread aufrufen oder noch eine Sekunde warten und dann erneut versuchen den Thread zu erstellen.
Mein Lösungsvorschlag:
void klientThreadStarten(int socket){
char name[32];
sprintf(name,"Client%d",gesamtAnfragen);
SceUID thid;
// Solange kein Thread erstellt werden konnte, wird versucht ein Thread zu erstellen. Dies wird solange versucht, bis es funktioniert
while ((thid = sceKernelCreateThread(name,klientBedienen,0x18,0x10000,0,NUL L)) /* hier ein "kleiner als"-Zeichen einfügen */ 0) {
printf("Thread %s: Warte auf Ressourcen\n", name);
sceKernelDelayThread(100);
}
// Erfolg: Der Thread hat genug Speicher bekommen
printf("Starte Thread %s : %d...\n",name,thid);
int tRueck = sceKernelStartThread(thid,sizeof(socket),&socket);
printf("Thread %s gestartet: %d\n",name,tRueck);
}
Außerdem solltest Du eventuell statt Dir die Rückgabewerte als Dezimalzahl darstellen zu lassen sie als hexadezimale Zahlen im Format "0x%08X" ausgeben lassen. Damit kannst Du direkt die Fehlercodes kontrollieren und erhältst keinen "Thread -270123112312". Positive Werte (im Falle des Erfolgs ) werden dann z.B. als "0x00000004" für "4" dargestellt. Wie gesagt, es ist nur eine Empfehlung.
Sorgst Du denn auch dafür, dass alte, abgelaufene Threads wieder gelöscht bzw. deren Speicher freigegeben wird? Wie organisierst Du die Threads? Speicherst Du sie in einer Liste oder startest Du sie einfach?
Wenn sie abgelaufen sind solltest Du am Ende ein sceKernelExitDeleteThread(0); in der klientBedienen-Methode aufrufen.
Hoffe, das hilft Dir erstmal. Wenn was is... Einfach melden
Dieser Beitrag wurde zuletzt bearbeitet: 13.01.2012 19:00 von vista200.
|
|
13.01.2012 18:55 |
|
Folgende User bedanken sich: |
|
The Real Enigma87
Legende
Beiträge: 1.345
Gruppe: User
Registriert seit: May 2010
Status:
Abwesend
Danke erhalten: 712
|
RE: Problem mit Threads
"Heroes??? There is no Such Thing."
Mandarin - Iron Man 3
|
|
14.01.2012 03:03 |
|
|
|
Gigor
Durchstarter
Beiträge: 72
Gruppe: User
Registriert seit: Jun 2011
Status:
Offline
Danke erhalten: 18
|
RE: Problem mit Threads
Hi,
Dankschön für die ausführliche Antwort.
Also bis jetzt mach ich das mit den Threads so, dass es eine Maximale Anzahl an laufenden Verbindungen (also auch Threads) gibt, und immer wenn ein Thread gestartet wird eins hoch zählt, bzw sich mit sceKernelExitDeleteThread beendet, wieder eins nach unten. Wenn eine Maximale Anzahl an Verbindungen erreicht ist, sollte es eigetnlich erst garkeine mehr annehmen. Macht er auch nicht..
Bis jetzt hab ich es auf 1.
Nach ner Zeit hatter sich dann aufgehängt, obwohl eigetnlich nur 3 Threads gleichzeitig laufen sollten (Der Main, einer Für ein Client und einer fürs steuern)
So, wenn ich die Stacksize auf 0x1000 (= 4096 Bytes) verringer geht garnichts, dann hängts sich gleich beim allerersten mal auf, allerdings ohne die "Warten auf Ressourcen" - Warnung auszugeben, die Schleife ist wohl übersprungen. 4kB sind wohl zu wenig..
Wenn ich Stacksize auf 0x10000 (= 64 kb) lasse, und die Max. Verbindungen auch auf 1. lasse (also nur eine UserAnfrage), hängt es sich zwar nicht mehr auf, aber nach ner Zeit isses trotzdem kaputt, weil anscheindend der Bedienthread nix mehr macht und so keine Verbindung mehr frei wird. Ich kann aber noch normal mit Kreis beenden (also der Kontroll-Thread läuft auch noch).Vielleicht ein fehlender Timeout oder so..
Wenn ich die max. gleichzeitigen Verbindungen auf 2 hochsetze, hängt es sich noch auf, an der gleichen stelle, aber es kommt keine Warnung (also die Schleife wird wohl übersprungen)
[Gerade beim Testen sehr komisch: Mit telnet/IE konnte ich auf server connecten, firefox hat gestreikt..]
Reicht es, einen Thread mit sceKernelExitDeleteThread zu beenden oder muss man noch irgendwelche aufräumarbeiten machen?
Kann es vielleicht sein, dass sich 2 Threads beißen wenn die aufs Netzwerk zugreifen oder so? Oder die sich sonst irgendwie nicht abkönnen?
Ich gugg weiter durch, vll hab ich noch irgendwo nen Bock, aber irgendwas scheint es damit zu tun zu haben.
Gigor
|
|
14.01.2012 16:39 |
|
|
|
vista200
Head of Awesomeness
Beiträge: 189
Gruppe: User
Registriert seit: Jul 2009
Status:
Offline
Danke erhalten: 139
|
RE: Problem mit Threads
Nach ner Zeit hatter sich dann aufgehängt, obwohl eigetnlich nur 3 Threads gleichzeitig laufen sollten (Der Main, einer Für ein Client und einer fürs steuern)
Hast Du einen Debug-Output, in dem Du sehen kannst, welcher Thread "stirbt" bzw. abstürzt? Was macht der "Steuer"-Thread?
So, wenn ich die Stacksize auf 0x1000 (= 4096 Bytes) verringer geht garnichts, dann hängts sich gleich beim allerersten mal auf, allerdings ohne die "Warten auf Ressourcen" - Warnung auszugeben, die Schleife ist wohl übersprungen. 4kB sind wohl zu wenig..
Hast Du noch andere Werte ausprobiert? 2kB z.B.?
Wenn ich Stacksize auf 0x10000 (= 64 kb) lasse, und die Max. Verbindungen auch auf 1. lasse (also nur eine UserAnfrage), hängt es sich zwar nicht mehr auf, aber nach ner Zeit isses trotzdem kaputt, weil anscheindend der Bedienthread nix mehr macht und so keine Verbindung mehr frei wird. Ich kann aber noch normal mit Kreis beenden (also der Kontroll-Thread läuft auch noch).Vielleicht ein fehlender Timeout oder so..
Wie ist denn der Main-Thread aufgebaut? Du lässt das Programm so lange laufen, wie Verbindungen eingehen, richtig? Also in etwa so:
while (((accept = accept()) /*größer-als-zeichen*/ 0) /* und und */ threadZaehler /* kleiner-als-zeichen*/ 1) {
// Thread erstellen und Socket-Nummer mitgeben
// Thread-Zähler + 1
}
Wenn es so läuft, dann wird der Main-Thread abgebrochen, weil der Thread-Zähler ja hochgesetzt wurde... Ich bin mir nicht sicher, welche Bedingungen für die Erfüllung des Schleifenbedingung bei Dir erforderlich sind.
[Gerade beim Testen sehr komisch: Mit telnet/IE konnte ich auf server connecten, firefox hat gestreikt..]
Firefox und alle anderen Server haben die Angewohnheit, mehrere Verbindungen zu öffnen und mehrere Daten gleichzeitig anzufordern. Hier lässt sich meist nur mit einem "einfachen" Telnet-Client arbeiten.
Liefert der Server denn auch den HTTP-Header mit, den der Browser braucht, um die Anfrage erfolgreich verarbeiten zu können?
Reicht es, einen Thread mit sceKernelExitDeleteThread zu beenden oder muss man noch irgendwelche aufräumarbeiten machen?
Das sollte reichen. Es sei denn, du allozierst via malloc() im Thread noch Speicher für die Testseiten oder so... Den solltest Du vor sceKernelExitDeleteThread() noch mit free(void*) freigeben, ansonsten entstehen Memory Leaks, die dazu führen, dass der belegte (aber nicht mehr gebrauchte) Speicher weiterhin als belegt gilt. Hier kannst Du z.B. beim Debuggen mit PSPLink die Belegung der RAM-Partitionen während der Ausführung einsehen.
Kann es vielleicht sein, dass sich 2 Threads beißen wenn die aufs Netzwerk zugreifen oder so? Oder die sich sonst irgendwie nicht abkönnen?
Eigentlich ist das nicht der Fall. Und falls doch, dann setze eine globale Variable "sendetGerade" auf "1", sobald ein Thread etwas senden möchte und wieder auf "0", sobald er damit fertig ist. Alle anderen Threads musst Du dann so programmieren, dass sie so lange mit dem Senden warten, bis "sendetGerade" wieder auf "0" steht. Aber aufgrund vom TCP-Protokoll sollte eigentlich jedes Paket - sofern fehlerfrei abgesendet - auch fehlerfrei beim Empfänger ankommen.
Du darfst mir gerne mal Deinen Quelltext schicken, ich habe mal ein ähnliches Projekt gehabt, allerdings nicht weiterverfolgt... Ich glaube aber auch, dass ein Webserver Anfragen nicht threaden muss, sondern sie nacheinander abarbeiten kann. Nur so ein Gedanke...
Dieser Beitrag wurde zuletzt bearbeitet: 15.01.2012 21:05 von vista200.
|
|
15.01.2012 21:02 |
|
Folgende User bedanken sich: |
|
Gigor
Durchstarter
Beiträge: 72
Gruppe: User
Registriert seit: Jun 2011
Status:
Offline
Danke erhalten: 18
|
RE: Problem mit Threads
Hi mal wieder,
hat jetzt en bisschen gedauert, hatte wenig zeit und bis ich psplink zum laufen gebracht hab..
Bin schon etwas weiter gekommen, aber erstmal die Lage.:
Also ich meine Hauptschleife ist in etwa so aufgebaut:
while(1){
if(verbdinung >= verbMax){continue}
/*verbindungen annehem*/
}
Stacksize hab ich jetzt auf 32kb.
Und mit dem HTTP sollte eigentlich funktionieren, Firefox stellt die Testseiten (C von a bis z offline Version^^) ganz gut dar, bisses halt abstürzt
Also ich glaub ich hab ein Hauptproblem gefunden.
Ich hatte nur eine Adressenstruktur für alle eingehenden Verbindungen (hab ich als nicht wichtig erachtet.) und das geht wohl nicht wenns mehrere gleichzeit sind^^:
Nungut, aber leider klappts immer noch nicht, irgendwann (ziemlich früh sogar) hängt sich ein Klientthread auf.
Mit der PSP-Link ausgabe kann ich bis jetzt garnix anfangen, nur dasses ein ClientThread verbockt
Die Andern Threds gehn aber noch. [Edit: Ist wohl nur wenn ich in PSP-LInk die prx starte, bei der normalen eboot hängt sichs ganz auf..]
host0:/> ./RedneckHTTP_Server.prx
Load/Start host0:/RedneckHTTP_Server.prx UID: 0x046EAD69 Name: RedneckHTTP
host0:/> Exception - Bus error (data)
Thread ID - 0x04A9B57D
Th Name - Client3
Module ID - 0x046EAD69
Mod Name - RedneckHTTP
EPC - 0x0882F34C
Cause - 0x1000001C
BadVAddr - 0x00000003
Exception - Address load/inst fetch
Status - 0x00088613
Thread ID - 0x04AC110D
zr:0x00000000 at:0x0BAE0F00 v0:0x00000000 v1:0x00000000
Th Name - Client4
a0:0x00000000 a1:0x00000000 a2:0x0000000F a3:0x0BFFFFF8
Module ID - 0x046EAD69
t0:0x08EFDBC0 t1:0x0FFAE0A8 t2:0x0BAE0A88 t3:0x089DE650
Mod Name - RedneckHTTP
t4:0x0FFFFFFF t5:0x00000000 t6:0xDEADBEEF t7:0x089555AC
EPC - 0x0882D43C
s0:0xDEADBEEF s1:0xDEADBEEF s2:0xDEADBEEF s3:0xDEADBEEF
Cause - 0x10000010
s4:0xDEADBEEF s5:0xDEADBEEF s6:0xDEADBEEF s7:0xDEADBEEF
BadVAddr - 0x00000003
t8:0x00000000 t9:0xDEADBEEF k0:0x0BAE0F00 k1:0x00000000
Status - 0x00088613
gp:0x08853C40 sp:0x0BAE0A70 fp:0x0BAE0A70 ra:0x08804A18
zr:0x00000000 at:0x08850000 v0:0xFFFFFFFF v1:0xFFFFFFFE
0x0882F34C: 0x8CE40008 '....' - lw $a0, 8($a3)
a0:0x0884B148 a1:0x08842D7C a2:0x0BAE8648 a3:0x00000000
host0:/>
t4:0x0884B610 t5:0x4406FF54 t6:0x000000DB t7:0x00000002
s0:0xFFFFFFFF s1:0x0884B148 s2:0x089DE5A0 s3:0x0884B148
s4:0xDEADBEEF s5:0xDEADBEEF s6:0xDEADBEEF s7:0xDEADBEEF
t8:0x000002E4 t9:0x000038E0 k0:0x0BAE8F00 k1:0x00000000
gp:0x08853C40 sp:0x0BAE8638 fp:0x0BAE8668 ra:0x0882D574
0x0882D43C: 0x8E020004 '....' - lw $v0, 4($s0)
Resetting psplink
Hier mal der gesamte Quelltext, falls du mal drüberguggen willst. Ist aber ziemlich unprofessionell^^
/* Gigor RedneckHTTP Server Versuch */
#include <sys/types.h>
#include <sys\socket.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <arpa/inet.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include <pspsdk.h>
#include <string.h>
#include <math.h>
#include <psputility.h>
#include <pspgu.h>
#include <pspgum.h>
#include <pspnet.h>
#include <pspnet_inet.h>
#include <pspnet_apctl.h>
#include "wurzelBumsNetDiag.c" /*Danke an Wurzelbums aus dem PSPKing Forum*/
#include <sys/fcntl.h>
#include <stdio.h>
#include <stdlib.h>
PSP_MODULE_INFO("RedneckHTTP", 0, 1, 1);
//Tippersparnis
#define printf pspDebugScreenPrintf
#define setPos pspDebugScreenSetXY
#define CRLF \r\n
//Request Typen
#define HTTP_GET 1
#define HTTP_POST 2
#define HTTP_HEAD 3
#define HTTP_UNKNOWN -1
//MAX etc
#define MAX_CLIENTS 2
#define MAX_VERBINDUNGEN 2
//Typen
typedef struct{
int typ;
char* text; //nullterminiert
} _httpHeader;
/*Bis jetzt nicht benutzt*/
typedef struct{
_httpHeader head;
size_t dataLength;
char* daten; //NULL wenn keine Daten (GET,HEAD etc.)
} _httpAnfrage;
//Funktionen Prototypen
_httpHeader *anfrageEmpfangen(int);
void headerFreigeben(_httpHeader*);
int httpTypBestimmen(char*);
int headerFertig(char*);
char *dateiRausfiltern(_httpHeader*);
void klientBedienen(int);
void dateiAusliefern(char*, int);
_httpHeader *antwortHeaderErstellen(int,int);
void klientThreadStarten(int);
void beendenFunktion();
//Variablen
int inSocket;
struct sockaddr_in serverAdresse;
int check;
int serverRennt = 1;
int gesamtAnfragen = 0;
int aktuelleVerbindungen = 0;
int main(){
SetupCallbacks();
pspDebugScreenInit();
gesamtNetDialogStart(); /*Danke an wurzelbums*/
/*Der Thread zum Beenden*/
SceUID bTh= sceKernelCreateThread("BEENDEN",beendenFunktion,0x18,0x4000,0,NULL);
sceKernelStartThread(bTh,0,NULL);
printf("BeendenThread eingerichet \n");
inSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(inSocket<0){printf("Fehler!");}
memset(&serverAdresse,0,sizeof(serverAdresse));
serverAdresse.sin_family = AF_INET;
serverAdresse.sin_port = htons(80);
inet_aton(INADDR_ANY,(struct sockaddr*)&serverAdresse);
check = bind(inSocket,(struct sockaddr*)&serverAdresse,sizeof(serverAdresse));
if(check<0){printf("Fehler bei bind \n");}
check = listen(inSocket,MAX_CLIENTS);
if(check<0){printf("Fehler bei listen \n");}
//struct sockaddr_in clientAdresse;
socklen_t len = sizeof(struct sockaddr);
/*Server Hauptschleife
Nimmt eine Verbindung an und startet dafür einen neuen Thread
Leider geht bis jetzt nur einer gleichzeitig
Wenn die Maximale Anzahl von Verbindungen erreicht wurde, wird eine kleine Puase eingelegt, bis sie nichtmehr erriecht ist.
*/
while(serverRennt){
if(aktuelleVerbindungen>=MAX_VERBINDUNGEN){
printf("#");
sceKernelDelayThread(10000);
continue;
}
printf("Wartet auf eine neue Anfrage\n");
/*Achtung memory leak - wird nicht freigegeben - nur zu testzwecken erstmal*/
struct sockaddr *adressenZeiger = malloc(len);
int testSock = accept(inSocket,adressenZeiger,&len);
gesamtAnfragen++;
if(testSock<0){sceKernelExitGame();}
printf("Neue Anfrage erhalten.\n");
klientThreadStarten(testSock);
aktuelleVerbindungen++;
}
/*Hier kommt es normal garnicht hin*/
printf("Ende");
sceKernelExitGame();
return 0;
}
_httpHeader *anfrageEmpfangen(int socket){
/*Empfängt solange daten, bis ein doppeltes CRLF kommt
Problem: Wenn noch andre Daten mitgesendet werden!
Rückgabewert: Ein Zeiger auf eine _httpHeader struktur, die alloziert wird.
Die muss dann irgendwann später wieder freigegeben werden!
*/
/*Todo:
TimeOut Einbauen
*/
_httpHeader *rueckgabe = malloc(sizeof(_httpHeader));
int requestTyp;
char puffer[1024];
char *anfrageText = NULL;
int gesamtEmpf = 0;
int fertig = -1;
anfrageText = malloc(1);
while(fertig<0){
int empf = recv(socket,puffer,1024,0);
anfrageText = realloc(anfrageText,gesamtEmpf+empf+2);
if(anfrageText == NULL){printf("Fehler bei Speicheralloziierung");return NULL;}
memcpy(&anfrageText[gesamtEmpf],puffer,empf); /*Kopiert den Puffer in den Speicher von Header*/
gesamtEmpf = gesamtEmpf + empf;
anfrageText[gesamtEmpf] = '\0'; //Nullterminieren;
/*Überprüfen ob header schon fertig empfangen ist*/
fertig = headerFertig(anfrageText);
}
requestTyp = httpTypBestimmen(anfrageText);
rueckgabe->typ = requestTyp;
rueckgabe->text = anfrageText;
return rueckgabe;
}
void headerFreigeben(_httpHeader *frei){
free(frei->text);
free(frei);
}
int httpTypBestimmen(char* adresse){
int check;
check = memcmp(adresse,"GET",3);
if(check==0){return HTTP_GET;}
check = memcmp(adresse,"POST",4);
if(check==0){return HTTP_POST;}
check = memcmp(adresse,"HEAD",4);
if(check==0){return HTTP_HEAD;}
return HTTP_UNKNOWN;
}
int headerFertig(char* adresse){
/*Header ist Fertig, wenn zwei \r\n kommen*/
char* erg = strstr(adresse,"\r\n\r\n");
if(erg==NULL){
//Nicht gefunden, also nicht fertig
return -1; //normal -1 nur zu test
}
else{
//Gefunden, also fertig
return 1;
}
/*Problem: Wenn nach dem Header noch daten kommen*/
}
char *dateiRausfiltern(_httpHeader *head){
/* Bekommt als Argument ein Zeiger auf eine _httpHeader Struktur.
Filtert die Zeichenkette für den Dateinamen heraus, alloziert dafür Speicher und gibt die Adresse zurück
Muss auch wieder freigegeben werden! Wird in der klientBedienen freigegebn
*/
char buffer[1024];
int pruef = sscanf(head->text,"%*s %s",buffer);
if(pruef!=1){printf("SscanfFehler %d",pruef);return NULL;}
printf("Anfrage erhalten nach Datei: %s \n",buffer);
int laeng = strlen(buffer);
if((laeng==1)&&(buffer[0]=='/')){strcpy(buffer,"index.html"); laeng = strlen(buffer);}
char *rueck = malloc(laeng+2);
rueck[laeng+1] = '\0'; //dass es sicher terminiert ist
if(rueck == NULL){printf("Malloc Fehler\n");return NULL;}
/*Wenn das erste zechen ein / ist solls weg */
if(buffer[0]=='/'){strcpy(rueck,&buffer[1]);}
else{strcpy(rueck,buffer);}
return rueck;
}
void klientBedienen(int sock){
_httpHeader *head = anfrageEmpfangen(sock);
char *pfad = dateiRausfiltern(head);
if(pfad==NULL){
printf("Fehlerhaften Request Empfangen!\n");
dateiAusliefern(NULL,sock);
}
dateiAusliefern(pfad,sock);
/*Speicher wieder freigeben*/
headerFreigeben(head);
free(pfad);
//evtl loggen();
printf("Anfrage komplett bearbeitet.\n\n");
aktuelleVerbindungen--;
sceKernelExitDeleteThread(0);
}
void dateiAusliefern(char* pfad, int sock){
char puffer[2048];
FILE *datei = fopen(pfad,"r");
printf("Suchte nach datei: %s\n",pfad);
if(datei==NULL){
/*Fehler, 404 Page ausgeben */
_httpHeader *antwHead = antwortHeaderErstellen(13,404);
printf("->Datei %s nicht gefunden, 404\n",pfad);
send(sock,antwHead->text,strlen(antwHead->text),0);
send(sock,"404 not found",13,0);
close(sock);
headerFreigeben(antwHead);
return;
}
/*Größe der Datei Bestimmen*/
fseek(datei,0,SEEK_END);
long gr = ftell(datei);
fseek(datei,0,SEEK_SET);
_httpHeader *antwHead = antwortHeaderErstellen((int)gr,200);
send(sock,antwHead->text,strlen(antwHead->text),0);
//Daten senden,
while(!feof(datei)){
size_t gel = fread(puffer,1,2048,datei);
int gesendet = send(sock,puffer,gel,0);
}
printf("->Datei %s wurde versendet\n",pfad);
fclose(datei);
close(sock);
headerFreigeben(antwHead);
}
_httpHeader *antwortHeaderErstellen(int contentLength,int status){
char puffer[2048];
int laenge = 0;
_httpHeader *rueck = malloc(sizeof(_httpHeader));
if(status==200){strcpy(puffer,"HTTP/1.0 200 OK\r\n");}
if(status==404){strcpy(puffer,"HTTP/1.0 404 Not found \r\n");}
strcat(puffer,"Server: RedneckHTTP Server PSP\r\nConnection: Close \r\n");
laenge = strlen(puffer);
sprintf(&puffer[laenge],"Content-Length: %d \r\n",contentLength);
strcat(puffer,"\r\n");
laenge = strlen(puffer);
rueck->text = malloc(laenge+1);
strcpy(rueck->text,puffer);
return rueck;
}
void klientThreadStarten(int socket){
char name[32];
SceUID thid;
sprintf(name,"Client%d",gesamtAnfragen);
while ((thid = sceKernelCreateThread(name,klientBedienen,0x18,0x8000,0,NULL ))<0) {
printf("Thread %s: Warte auf Ressourcen\n", name);
sceKernelDelayThread(100);
}
printf("Starte Thread %s ; ID: 0x%8X ...",name,thid);
//Hier hängt sichs auf:
int tRueck = sceKernelStartThread(thid,sizeof(socket),&socket);
printf("...Thread %s gestartet\n",name);
}
void beendenFunktion(){
SceCtrlData pad;
while(1){
sceCtrlReadBufferPositive(&pad,1);
if(pad.Buttons&PSP_CTRL_CIRCLE){
printf("-->SERVER wird beendet<--");
sceKernelExitGame();
}
sceKernelDelayThread(100000);
}
}
//{TESTZWECKE
/*Testzwecke
struct sockaddr_in clientAdresse;
socklen_t len = sizeof(clientAdresse);
printf("Warte auf Anfragen\n");
int testSock = accept(inSocket,(struct sockaddr*)&clientAdresse,&len);
printf("Anfrage erhalen\n");
char puffer[2048];
recv(testSock,puffer,2048,0);
char testnachr[] = "HTTP/1.0 200 OK \n\rServer: PSP \n\rContent-Length: 10\n\r Connection: Close\n\r\n\rTestTest12";
send(testSock,testnachr,strlen(testnachr),0);
close(testSock);
Ende Testzwecke*/
//}
[das stellt das manche Zeichen falsch dar..]
dankende grüße
Gigor
Edit:
So, ich bin ein ganz kleinen Schritt weiter, der 2. Thread hängt sich wohl ganz am Anfang auf, direkt bei "empfange Anfrage"
host0:/> BeendenThread eingerichet
Wartet auf eine neue Anfrage
Neue Anfrage erhalten.
Starte Thread Client1 ; ID: 0x 4AA2D55 ...Empfange Anfrage..
...Thread Client1 gestartet
Wartet auf eine neue Anfrage
Anfrage fertig empfangen, filtere Dateinamen
Anfrage erhalten nach Datei: /a/index.htm
Pfad herausgefiltert, liefere datei aus...
Suchte nach datei: a/index.htm
Neue Anfrage erhalten.
Starte Thread Client2 ; ID: 0x 4A9B165 ...Empfange Anfrage..
...Thread Client2 gestartet
#####################->Datei a/index.htm wurde versendet
Anfrage komplett bearbeitet.
Exception - Bus error (data)
Thread ID - 0x04A9B165
Wartet auf eine neue Anfrage
Th Name - Client2
Neue Anfrage erhalten.
Module ID - 0x043D7C07
Mod Name - RedneckHTTP
EPC - 0x0882F380
Starte Thread Client3 ; ID: 0x 4ABEF73 ...Empfange Anfrage..
Cause - 0x1000001C
BadVAddr - 0x00001434
Status - 0x00088613
Anfrage fertig empfangen, fiAnfrage fertig empfangen, filtere Dateinamen
zr:0x00000000 at:0x0BAE0F00 v0:0x00000000 v1:0x00000000
a0:0x00000000 a1:0x00000000 a2:0x0000000F a3:0x0BFFFFF8
#Anfrage erhalten nach Datei: /a/common/prettify.css
Pfad herausgefiltert, liefere datei aus...
t0:0x08F00E00 t1:0x0FFAE0A8 t2:0x0BAE0A88 t3:0x089E1890
t4:0x0FFFFFFF t5:0x00000000 t6:0xDEADBEEF t7:0x08957CAC
Suchte nach datei: a/common/prettify.css
s0:0xDEADBEEF s1:0xDEADBEEF s2:0xDEADBEEF s3:0xDEADBEEF
s4:0xDEADBEEF s5:0xDEADBEEF s6:0xDEADBEEF s7:0xDEADBEEF
t8:0x00000000 t9:0xDEADBEEF k0:0x0BAE0F00 k1:0x00000000
gp:0x088563B0 sp:0x0BAE0A70 fp:0x0BAE0A70 ra:0x08804A1C
0x0882F380: 0x8CE40008 '....' - lw $a0, 8($a3)
#->Datei a/common/prettify.css wurde versendet
Anfrage komplett bearbeitet.
Wartet auf eine neue Anfrage
Neue Anfrage erhalten.
Starte Thread Client4 ; ID: 0x 4A95905 ...Empfange Anfrage..
Anfrage fertig empfangen, filtere Dateinamen
Anfrage erhalten nach Datei: /a/common/prettify.js
Pfad herausgefiltert, lieferPfad herausgefiltert, liefere datei aus...
#Suchte nach datei: a/common/prettify.js
#########->Datei a/common/prettify.js wurde versendet
#Anfrage komplett bearbeitet.
Wartet auf eine neue Anfrage
--------
Log aus Firefox:
[17:54:49.480] GET http://192.168.2.105/a/index.htm [HTTP/1.0 200 OK 406ms]
[17:54:49.541] GET http://192.168.2.105/a/common/galileo_open.css
[17:54:49.547] GET http://192.168.2.105/a/common/prettify.css [HTTP/1.0 200 OK 360ms]
[17:54:49.553] GET http://192.168.2.105/a/common/prettify.js [HTTP/1.0 200 OK 485ms]
DEADBEEF hört sich verdächitig an
Neuer Edit:
Jetzt ist sogar einmal der user_main abgeschmiert.. ich glaub ich geb auf...[Ok ist en anderes Error sehr ich gerade (load adresse/inst fetch), resultiert vll aus error 1]
host0:/> RedneckHTTP_Server.prx
Load/Start host0:/RedneckHTTP_Server.prx UID: 0x043F7571 Name: RedneckHTTP
host0:/> BeendenThread eingerichet
Wartet auf eine neue Anfrage
Neue Anfrage erhalten.
Starte Thread Client1 ; ID: 0x 4ABB42D ...Empfange Anfrage..
Alloziere Speicher für HTTP_Header in Anfrage Empfangen
Speicherallozierung _Header Speicherallozierung _Header fertig
malloc für AnfrageText in Empmalloc für AnfrageText in Empfangen
malloc für text fertig. Starte Empfangenschleife
Schleife: empfangen
Schleife: empf fertig, reallc
Schleife: realloc fertig, memcpy
Schleife: memcpy fertig, termiere + überprüfe ob fertig
Empfangen schleife Beendet, funktion fast fertig
Anfrage fertig empfangen, filtere Dateinamen
Anfrage erhalten nach Datei: /a/common/9783836211161_s.gif
Pfad herausgefiltert, liefere datei aus...
Suchte nach datei: a/common/9783836211161_s.gif
Neue Anfrage erhalten.
Starte Thread Client2 ; ID: 0x 4A8F03D ...Empfange Anfrage..
Alloziere Speicher für HTTP_->Datei a/common/9783836211161_s.gif wurde versendet
en
#Speicherallozierung _Header fertig
wurde versendet
#Speicherallozierung _Header fertig
malloc für AnfrageText in Emp
alloc für AnfrageText in Empfangen
mmalloc für text fertig. Starte Empfangenschleife
Schleife: empfangen
Schleife: empf fertig, reallc
Schleife: realloc fertig, memcpy
Exception - Bus error (data)
Thread ID - 0x04A8F03D
Th Name - Client2
Wartet auf eine neue Anfrage
Exception - Address load/inst fetch
Module ID - 0x043F7571
Thread ID - 0x043D137D
Mod Name - RedneckHTTP
Th Name - user_main
EPC - 0x0882F410
Module ID - 0x043F7571
Cause - 0x1000001C
Mod Name - RedneckHTTP
BadVAddr - 0x00001434
EPC - 0x0882EF68
Status - 0x00088613
Cause - 0x10000010
zr:0x00000000 at:0xDEADBEEF v0:0x00000000 v1:0x00000000
BadVAddr - 0x00000003
a0:0x00000000 a1:0x00000000 a2:0x0000000F a3:0x0BFFFFF8
Status - 0x20088613
t0:0x08F007C0 t1:0x0FFAE0A8 t2:0x0BAE0A88 t3:0x089E1250
zr:0x00000000 at:0xDEADBEEF v0:0x00000001 v1:0xFFFFFFFC
t4:0x0FFFFFFF t5:0xDEADBEEF t6:0xDEADBEEF t7:0xDEADBEEF
a0:0x0884E0B0 a1:0x00004000 a2:0x00044001 a3:0x00000038
s0:0xDEADBEEF s1:0xDEADBEEF s2:0xDEADBEEF s3:0xDEADBEEF
t0:0xFFFFFFDC t1:0x00000038 t2:0x0884DEF8 t3:0xFFFFFFFC
s4:0xDEADBEEF s5:0xDEADBEEF s6:0xDEADBEEF s7:0xDEADBEEF
t4:0x0884E0B0 t5:0xDEADBEEF t6:0xDEADBEEF t7:0xDEADBEEF
t8:0xDEADBEEF t9:0xDEADBEEF k0:0x0BAE0F00 k1:0x00000000
s0:0xFFFFFFFF s1:0x00000020 s2:0x0884DAC8 s3:0x0BABFEE0
gp:0x088565C0 sp:0x0BAE0A70 fp:0x0BAE0A70 ra:0x08804A8C
s4:0x0000001E s5:0x00000013 s6:0x0884DEF0 s7:0xDEADBEEF
0x0882F410: 0x8CE40008 '....' - lw $a0, 8($a3)
t8:0xDEADBEEF t9:0xDEADBEEF k0:0x0BABFF00 k1:0x00000000
gp:0x088565C0 sp:0x0BABFDF0 fp:0x0BABFE10 ra:0x0882EBA4
0x0882EF68: 0x8E020004 '....' - lw $v0, 4($s0)
Dieser Beitrag wurde zuletzt bearbeitet: 25.01.2012 18:45 von Gigor.
|
|
22.01.2012 17:42 |
|
|
|
Gigor
Durchstarter
Beiträge: 72
Gruppe: User
Registriert seit: Jun 2011
Status:
Offline
Danke erhalten: 18
|
RE: Problem mit Threads
Falls es noch jemand interessiert hab mich mal wieder drangesetzt und hab jezt ein halbwegs "stabilen" Server hinbekommen.
(Firefox hängt bei großen seiten zwar, aber der server läuft noch Also einfache Bilder oder so werden aber schon angezeigt)
Wer intersse hat einfach melden.
PS: Hab das Problem umgangen indem ich bei der Threaderzeugung keine Argumente übergeben hab und alles mit Globalen Variablen gemacht hab
Dieser Beitrag wurde zuletzt bearbeitet: 30.05.2012 18:30 von Gigor.
|
|
30.05.2012 18:29 |
|
|
|