Socket send()
-
Danke, habs gefunden.
-
Die ganze Sache ist mir jetzt doch noch nicht ganz klar.
Wenn ich z.B mit
int sock = accept(...);
einen Socket definiere, woher bekomme ich dann die Socketstrucktur zu diesem Socket ???
PS: Google hilft mir nicht wirklich weiter.
Danke
-
Geht es nicht eher um sowas wie Keepalive? Wenn du keine speziellen Vorkehrungen triffst, kriegst du das EPIPE ja eh nie zu sehen, da du per SIGPIPE vor die Tür gesetzt wirst. Prinzipiell kann man dazu nur sagen, dass TCP-Verbindungspartner nicht aktiv Pakete austauschen, wenn gerade keine gesendet werden. Theoretisch kann der eine Jahrelang eine TCP-Verbindung offen haben, obwohl der andere Rechner inzwischen vom Netz genommen und dem Reycling zugeführt wurde
Es gibt eine Socketoption namens Keepalive, aber die checkt auch nur alle 2 Stunden oder so ... was schließen wir daraus? Man nimmt es ins Protokoll auf. Exemplarisch wär da zb das irc-Protokoll, wenn ein Client auf eine PING-Nachricht nicht innerhalb einer bestimmten Zeit mit PONG antwortet wird die Verbindung getrennt.
-
Nein, es geht darum die maximale Verbindungsanzahl zu begrenzen. Mit der send() Option MSG_NOSIGNAL kann man dem SIGPIPE entgehen. Natürlich überprüfe ich auf EPIPE und schliesse dann die Verbindung.
Stell die aber mal folgende ( OK, sehr unwahrscheinliche ) Situation vor:
Es verbinden sich so viele Clients das die maximale Benutzeranzahl erreicht ist, danach trennen sich wieder alle ohne Daten angefordert zu haben. Danach ist aber der Server komplett blockiert, da er nicht erkennen kann dass sich Clients getrennt haben. Und genau diese Ausnahme versuche ich aufzufangen.
@patrick++
Kannst du mir mal ein Beispiel oder Link zur Strucktur socket angeben? Hab zwar die Def. gefunden weiss aber nicht wie ich das ganze anwenden soll.
Danke
-
Original erstellt von pasti:
[QBEs verbinden sich so viele Clients das die maximale Benutzeranzahl erreicht ist, danach trennen sich wieder alle ohne Daten angefordert zu haben. Danach ist aber der Server komplett blockiert, da er nicht erkennen kann dass sich Clients getrennt haben. [/QB]genau dafür würd ich select verwenden. bau dein protokoll einfach so auf, dass der client zur begrüsung was senden muss. auf der serverseite baust du ein recv mit nem angemessenem timeout (-> select!). empfängst du innerhalb dieses timeouts nix, wars ein fake-connect und du killst die verbindung einfach.
noch ein tip: den letzten socket offen lassen, damit du weiteren connectenden clients mitteilen kannst, dass der server voll ist.
-
pasti: Wenn du im select mit einer Anzahl Clients hängst, und einer trennt die Verbindung, dann kehrt select doch zurück und sagt dir, dass Daten zum Lesen anstehen (und zwar 0 Byte für EOF aber trotzdem). Ich hab das jetzt nicht überprüft, aber es erscheint mir logisch. Hast du das schon probiert?
-
(bei poll(2) gibt es dafür das Flag POLLHUP (Hung up))
-
Das einfachste wäre schon das Protokoll so zu definieren, dass der Client zum Verbindungsanfang und zum Verbindungsende einen definerten String senden muss.
Meine Bibliothek ist aber etwas speziell in der Zielgruppe.
Sie ist nämlich dazu da Macromedia Flash Clients zu verwalten. Die Zielgruppe sind also Personen welche sich nicht gut mit Programmiersprachen auskennen bzw. Personen die nicht für einen simplen Chat die ganzen Socketfunktionen durchkauen wollen.
Das führt zu zwei Vorraussetzungen:
Erstens soll das Protokoll sehr einfach auf Flashseite zu implementieren sein.
Zweiten "tötet" jeder den Flashclient wenn er den Browser schliesst, ohne irgenein "Please disconnect me!" Befehl an der Server zu senden.
Kann mir jemand das mit dieser Socketstrucktur erläutern, dass wäre nämlich ziemlich das was ich suche ( glaube ich zumindest ).
Danke
MFG pasti
-
die Verbindung wird geschlossen, wenn der Client getötet wird. Das bekommst du auch auf deiner Seite mit, da ein read 0 zurückliefern, bzw. write EPIPE/SIGPIPE verursachen würde.
Wo genau ist jetzt dein Problem?
PS: von dieser ominösen socket-Struktur hab ich noch nie was gehört, ist das was Linux-spezielles?
-
Schau dir mal http://www.cl.cam.ac.uk/Teaching/2002/DigiComm2/sheet2.pdf an.
Dort wird das Ganze gezeigt.
Werd aber nicht schlau draus, ist ein Socket jetzt
int s = socket(...); //oder irgendwas struct socket s;
Read liefert doch auch 0 zurück wenn der Client einfach nichts gesendet hat, aber noch verwendet wird.
Meine jetzige Lösung verwendet send() bzw. write(). Wenn mehr als 90% der maximalen Clientanzahl erreicht ist sende ich an alle Clients ein Zeichen, prüfe auf EPIPE und trenne danach die "getrennten" Verbindungen um Platz für neue Verbindungen zu schaffen. ABER dann muss ich jedem FlashClient sagen er soll dieses Zeichen ignorieren.
Wenn der Client in C++ oder so geschrieben wäre wäre das ganze kein Problem. Aber mit Flash ist das Überladen ganzer Funktionen sehr mühsam. Und das Ziel dieser Bibliothek besteht darin das ganze möglichst einfach zu halten, so das auch jemand der erst ein paar Stunden programmiert die Bibliothek handhaben kann, sowol auf Flash als auch auf C++ Seite.
Achja, der Tipp den letzten Socket offen zu lassen ist ist wirklich nützlich (warum bin ich nicht drauf gekommen ??? ).
MFG Pasti
[ Dieser Beitrag wurde am 05.03.2003 um 21:47 Uhr von pasti editiert. ]
-
Original erstellt von pasti:
**
Read liefert doch auch 0 zurück wenn der Client einfach nichts gesendet hat, aber noch verwendet wird.
**wo steht das?
On success, the number of bytes read is returned (zero
indicates end of file)-- read(2)