-
Hallo liebe Community,
ich bin gerade dabei einen Socketserver + Client (TCP/IP) zu programmieren und habe noch einige grundsätzliche Fragen und werde bestimmt auch noch in kommender Zeit einige weiter Fragen haben, deswegen erstelle ich diesen Thread. Bin gerade erst dabei, mich in die Materie einzuarbeiten.
1. Kann ich ausschließen, dass es zu 0/1 Verdrehern kommt?
Beispiel:
3. Ist malloc sehr rechenintensiv? Ich arbeite mit pThreads und da ist die Frage, ob ich jedem Thread von Anfang an einen gewissen Platz im Stack freihalte oder je nach Bedarf mit malloc akquiriere. Ich möchte nicht, dass mein Server eine lahme Schnecke wird, weil er ständig damit beschäftigt ist den Speicher neu zu verwalten.Code :1 2 3 4 5
Client: send(socket, „123\0“, 4, 0); Server: recv(socket, char, 4, 0); printf(„%s\n“, char); => gibt zum Beispiel 112 aus
4. Wenn ein pThread (Serverseitig) gerade nichts für seinen Client tun kann, würde ich ihn gerne um Ressourcen zu sparen so lange mit pthread_cond_wait warten lassen.
Ist es möglich, dass der Client das pthread_cond_signal an den ja eigentlich schlafenden Thread sendet um ihn wieder aufzuwecken, wenn der Server dem Client vorher seine Adresse verrät? Dürfte ja eigentlich nicht gehen, da der Thread, der auf den Client hört ja derjenige ist, der schläft.
Oder gibt es hierfür eine bessere Möglichkeit oder ein go-around?
Vielen Dank für eure Mühen und Antworten!
Mit freundlichen Grüßen
Genius
-
1) TCP oder UDP (STREAM / DGRAM)?
Bei UDP ist nicht wirklich garantiert, wie und ob die Daten ankommen,
dafür ist es etwas schneller als TCP-
Bei TCP kann/darf sowas nicht passieren, da muss der Fehler wo anders sein.
Wie sind den die Rückgabewerte?
Vllt. ist ja ein Fehler aufgetreten?
Returnwert unter 0 ist Fehler, genau 0 ist keine Verbindung.
Sonst die Byteanzahl., über 0.
Ein anderes mögliches Problem: send/recv müssen sich nicht an die Länge 4 halten.
Sie sind nur "verpflichtet", min. 1 und max. 4 Bytes zu verarbeiten.
send kann also zB. 4 Byte senden, aber recv nur 1 empfangen.
Um dann die restlichen 3 zu bekommen muss man recv öfter aufrufen,
bis man insgesamt 4 Byte hat.
Ca. so (auch gleich mit Fehlerprüfung):
Für send ziemlich gleich, dafür muss es aberCode cpp:1 2 3 4 5 6 7 8 9 10 11 12 13
int r, bytes, i; ... bytes = 4; //Genau 4 Bytes empfangen i = 0; while(i < bytes) { r = recv(socket, &variable[i], bytes - i, 0); if(r > 0) i += r; else if(r < 0) printf("Fehler %d\n", r); else printf("Keine Verbindung"); }
eine char-Array-Variable sein (kein fixes Literal wie "123")
2) Kommt auf die Speichermenge an.
Wenn jeder Thread zB. bis zu 100MB brauchen kann,
besser erst bei Bedarf reservieren.
Bei normaleren Mengen würde ich gleich von Anfang an.
3) Du willst also praktisch ein sleep,
das aber bei Clientaktivität unterbrochen werden kann.
a) könnte recv das selbst.
Solange kein Byte vom Client kommt, wird sehr resourcenschonend gewartet.
Problem: Wenn der Threads mit anderen kommunizieren muss
(wenns auch nur die Beenden-Meldung ist etc.)
b) Die Funktion select
Man gibt einen (oder mehrere) Sockets,
dann wird gewartet, bis er was geschickt bekommt.
Vorteil zu recv selbst: Es gibt ein Timeout.
In einer Schleife immer select, das auch bei Nicht-Empfang naxh xv Millisekunden
fertig ist, dann die anderen Threadaufgaben, dann wieder select...
Anwendungsbeispiel hier: http://www.c-worker.ch/tuts/select.php#server
GrußNetiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Schonmal vielen Dank!
Ich arbeite mit TCP/STREAM. Bisher kamen die Daten immer wunderbar an, ich wollte es nur theoretisch wissen, ob es zu 0/1 Fehlern kommen kann. Wäre nämlich ziemlich fatal, wenn Cleint und Server verschiedene Datensätze besitzen!
Danke für die Schleife, werde das in meine Funktion einbauen!
Freue mich auf den Rest =)!
Mit freundlichen Grüßen
Genius
-
Rest ist jetzt oben.
Also, bei TCP kommen die Daten unverändert an.
Entweder liegts am eigenwilligen Mengenverhalten der Funktionen,
oder am restlichen Code.
Kannst ja mit zB. Wireshark überprüfen, was da übertragen wird.Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Ich habe ein weiteres Problem ... bzw. ich stehe gerade irgendwie auf dem Schlauch!
Ich habe (ganz grob) folgenden Aufbau:
Ich hoffe ich habe nichts vergessen, was zum verstehen meines Problems erheblich ist.Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
int y = 0; pthread_function() { accept(); y = 0; } main () { bind(); listen(); while(1) { if(y == 0) { y = 1; pthread_create() } } }
Das Programm startet -> socket wird gebunden und lauscht; y wird auf 1 gestellt. Wenn nun eine Client-Anfrage kommt, wird sie akzeptiert.
Mein Problem ist, dass die while(1) – Schleife während keine weiter Anfrage kommt völlig unnötig läuft und läuft und läuft … und schön brav mit nichts und wieder nichts meinen Prozessor auslastet. Am liebsten würde ich sie „blocken“ bis y wieder 0 ist ...
Ist mein Problem verständlich? Wie mache ich das?
Sieht mir nach einem sehr dummen Denkfehler aus :-D. Danke für eure Hilfe!
Mit freundlichen Grüßen
Genius
-
In der pthread_function wird also nicht nur akzeptiert,
sondern alles bis zum Schließen gemacht,
und die Schleife geht sinnlos.
Mach doch etwas wie
in die Schleife.Code cpp:1 2
if(besetzt) sleep(1); //1 Millisekunde
Kein wirkliches Anhalten, aber die Prozessorlast ist weg.
Könnt nur eventuell Probleme machen, wenn sehr viele Verbindungen da sind.
(Aber diese 1-Client-Methode macht dann die größeren Probleme).Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Ein sleep ist mir zu unsauber - auch nicht Sinn und Zweck der Sache - gibt sonst u.U. wie Sie schon richtig gesagt haben einen mega Stau ...
Es ist keine 1-Client-Methode, der Thread macht seine Arbeit erst, nachdem y wieder auf 0 gestellt ist.Aber diese 1-Client-Methode macht dann die größeren Probleme
Trotzdem schonmal Danke!
Mit freundlichen Grüßen
Genius
-
03.02.12 10:24 #8
- Registriert seit
- Mar 2008
- Beiträge
- 147
Hallo,
ein Sleep finde ich nicht unsauber. Du musst dir immer überlegen, dass ein Prozessor eh niemals richtig angehalten werden kann. Dafür gibt es den Leerlaufprozess, der auch nichts anderes macht als immer wieder 1/2 zu rechnen o.ä.. Ein Sleep ist ansich sogar sehr schön: Er sagt dem Prozessor, dass er erstmal keine Rechenzeit mehr braucht und stellt diese dann dem Prozessor wieder zur Verfügung.
Als Alternative könntest du das ganze auch mit WaitForSingleObject() lösen. Eventuell auch WaitForMultipleObjects() [Ich habe jetzt dein Problem nicht im Detail angeschaut].
Im übrigen: Integers sind meines Wissens nach threadsafe. Allerdings solltest du dir im generellen immer überlegen, ob du von mehreren Seite ungeschützt auf eine Variable zugreifen solltest...
Die Frage wäre auch, wieviele gleichzeitige Verbindungen du für dein Programm erwartest, sodass ein Sleep von 1ms zu lange dauern würde?
Gruß,
kickerxyhilfreiche Antwort? Es gibt einen Danke-Button ;)
Rettet das Internet!
-
Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Vielen Dank, das hat mir schon mal sehr weitergeholfen!
Ja, weiß ich - in diesem Fall (y) ist es unmöglich, dass zwei threads gleichzeitig darauf zugreifen. Trotzdem vielen Dank für den hinweis =)!Im übrigen: Integers sind meines Wissens nach threadsafe. Allerdings solltest du dir im generellen immer überlegen, ob du von mehreren Seite ungeschützt auf eine Variable zugreifen solltest...
Ich hatte eigentlich vor die threads mit pthread_attr_setstacksize den stack "verbrauch" auf ein minimum herunter zu brechen, zudem die threads die nichts zu tun haben brav schlafen lassen ...Weiterer Punkt: Für so viele Verbindungen je einen Thread bereitstellen
ist auch nicht gerade unbelastend.
Ein Thread pro 64-Socket-Block ist eventuell besser...
Wenn es zu viele Anfragen werden, muss dann eben u.U. ein vielkerniger Prozessor her um alle threads zu verarbeiten ...
Vielen Dank!
Mit freundlichen Grüßen
Genius
-
Hast du meinen Beitrag auch mal gelesen?
Vielkerniger Prozessor ist ziemlich teurer Spaß, auf jedem Rechner...
Warum nicht select etc.?Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Hallo, ich habe ein weiteres Problem:
Wenn ich Zeichen versende, die über die 127 ANSI Zeichen hinausgehen, dann sind die Chars ja auf einmal größer ... und werden daraufhin noch dazu falsch von meiner MySQL tabelle interpretiert.
z.B. wird ä wird zu 'ä' und das letzte Zeichen des Strings fällt raus ...
Wie verschicke ich am Besten Texte über einen Socket-Server?
Vielleicht werden ja auch irgendwann chinesische Zeichen versendet ... soll ich die Strings in int arrays umwandeln und mich auf eine Codierung festlegen, oder wie mach ich das am dümmsten?
Vielen Dank für die Hilfe!
Mit freundlichen Grüßen
Genius
-
Auch wenn du es gut ignorierst, ein Thread pro Socket frisst Leistung.
Zum neueren Problem:
Die chars werden nicht größer, bleiben immer 1 Byte.
Die scheinbare Verdoppelung hängt auch mit dem Zeichensatz zusammen.
Verwende Convert.
Zu den chinesischen (etc.) Zeichen: Falls es wirklich internationalisierbar sein soll
musst du schon das C-Programm anpassen, nicht erst den SQL-Teil.
Kein Iso8859-1 mehr, sondern zB. Utf8.
Es existieren auch verschiedene Libs, die den Umgang erleichtern.Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Mein code sieht nun so aus - und trotzdem wird der Datensatz von der SQL-Datenbank nicht richtig interpretiert:
Code :1 2 3 4 5 6
char buchstabenkette[] = "-§xÄ" char query_insert[190]; sprintf(query_insert, "INSERT INTO tabellenname (spaltenname) VALUES (CONVERT('%s' USING utf8)), buchstabenkette); mysql_query(verbindung, query_insert);
In der Datenbank steht dann: -§xÄ
Die Spalte ist mit utf8_general_ci konvertiert.
Was mache ich falsch?
Mit freundlichen Grüßen
GeniusGeändert von Genius (05.02.12 um 12:34 Uhr)
-
Du musst auch den derzeitigen Zeichensatz angeben.
Siehe erstes Beispiel im Link:
_latin1'%s' ...Code sql:1
CONVERT(_latin1'Müller' USING utf8)
Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
Ähnliche Themen
-
[C++] pthreads/opengl Problem
Von Unicate im Forum C/C++Antworten: 13Letzter Beitrag: 11.07.11, 11:19 -
[C++ VCL Builder von Borland] SocketServer soll ClientID ausgeben
Von xLx im Forum C/C++Antworten: 4Letzter Beitrag: 03.12.08, 08:42 -
Perl Script (SocketServer) auf nem Hoster gestartet: Wie beende ich den Wieder?
Von Marius Heil im Forum CGI, Perl, Python, Ruby, Power ShellAntworten: 0Letzter Beitrag: 02.03.08, 17:02 -
Socketserver
Von Rocco1979 im Forum JavaAntworten: 0Letzter Beitrag: 01.11.07, 13:49



2Danke

Zitieren


Login






