PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PHP-Server von socket trennen



Andislack
27-07-2006, 21:06
Hi,

ich habe einen eigenen PHP-Server geschrieben. Der funktioniert auch wunderbar.
Wenn ich den Server aber "herunterfahre" mit socket_close( $sock ); und exit; um ihn danach sofort wieder zu starten, bekomme ich die Fehlermeldung:
"socket_bind() fehlgeschlagen: Grund: Address already in use"

Warte ich jetzt einen Moment (unterschiedlich lange, bis 2 Minuten manchmal), bis das BS den Socket wieder freigibt, kann ich den Server wieder normal starten.

Wie kann ich den Server sauber und vorallem sofort von seinem socket trennen, so dass er direkt wieder gestartet werden kann?
Geht das, wenn ja wie?

Der Socket wird so erstellt:

$sock = @socket_create( AF_INET, SOCK_STREAM, 0 );
$ret = @socket_bind ( $sock, ADRESS, IMODD_PORT );
$ret = @socket_listen( $sock, 5 );

Schließen tue ich so:


$sock_close = @socket_close( $sock );
exit;

Kann mir jemand nen Tipp geben? Auch über einen Umweg...
Danke Gruss Andi

undefined
27-07-2006, 21:21
genau durchlesen ;)
http://www.php.net/manual/de/function.socket-accept.php

Andislack
28-07-2006, 08:52
Hallo,

ich kann deinen Tipp nicht ganz deuten.
Meinst du das hier aus dem Manual:

Falls es keine wartenden Verbindungsanforderungen gibt, blockiert die Funktion socket_accept() so lange, bis eine Verbindungsanforderung kommt.

Also direkt den Socket von socket_accept() schließen? Das hatte ich schon ausprobiert.
Ich habe schon alle möglichen Varianten des socket_close durchprobiert, aber immer das gleiche Resultat.

Oder du kannst deinen Tipp vielleicht etwas präzisieren ;-) ?

Andi

undefined
28-07-2006, 11:03
Du kannst nur einen Socket Schließen wenn er zuvor mit socket_accept() geöffnet wurde. Siehe auch die Erklärung zu socket_close(). Andernfalls wird php das close Ignorieren.

Andislack
28-07-2006, 11:56
sorry, das hatte ich in meinem ersten Post nicht geschrieben.
socket_accept() ist natürlich erfolgt.
Aber das stimmt so nicht, wie du es sagst.
Manual zu socket_close() sagt:

...die mit socket_create() oder socket_accept() erzeugt wurden.

Aber es funktioniert trotzdem nicht.
Vielleicht sollte ich erwähnen, dass ich mich im Server einlogge und sozusagen einen remote-shutdown mache.
D.h. vereinfacht dargestellt:


$sock = @socket_create( AF_INET, SOCK_STREAM, 0 );
$ret = @socket_bind ( $sock, ADRESS, IMODD_PORT );
$ret = @socket_listen( $sock, 5 );
do
{
$msgsock = socket_accept( $sock );
$buf = socket_read( $msgsock, 4096 );

if ( "remoteshutdown" == $buf )
{
$arrOpt = array('l_onoff' => 1, 'l_linger' => 1);
socket_set_block( $sock );
socket_set_option( $sock, SOL_SOCKET, SO_LINGER, $arrOpt );
$sock_shutdown = socket_shutdown( $sock );
$sock_close = socket_close( $sock );
}
}
while (true);

muss ich jetzt $msgsock auch nochmal explizit schließen und $ret vielleicht auch noch? Spielt da die Reihenfolge eine Rolle, welcher Socket zuerst geschlossen wird?

Ich habe (leider) auch noch keinen gefunden, der ein ähnliches Problem beschreibt.

Andi

undefined
28-07-2006, 12:00
Ja die Reihenfolge ist sehr entscheident.
Das erklärt dann auch deine Fehlermeldung, weil unix den Prozess eine weile stehen läßt bis er ins Nirvana geschickt wird. So etwas kannst du mit (shell lsof) am besten überwachen um sehen ob dein Programm sauber läuft..


<?php
/** Client beenden */
if ( $buffer == "clientquit" ) {
socket_close($new_socket);
/** Client und Server Beenden */
} else if ( $buffer == "serverquit" ) {
echo "Server Shutdown";
socket_close($new_socket);
socket_close($socket);
exit(0);
}
?>

undefined
28-07-2006, 12:07
PS: $buffer ist

$buffer = socket_read( $new_socket, 1024 );

Andislack
28-07-2006, 13:16
also erstes Problem gelöst :-)
Es war die ganze Zeit noch ein weiterer Client eingeloggt, was ich nicht bemerkt hatte.
Daher war es dann ja klar, warum es nicht ging.

Aber jetzt gehts und ist sauberer, da ich die anderen Sockets ja nicht geschlossen hatte. ;-)

Danke für die Hilfe.
Gruss Andi