hallo
ich entwickle grade ein TCP Server und Client, da das in meiner Anwendung
leider notwendig ist.
der server läuft nur in einem prozess und kann aber mit mehreren clients
aufeinmal arbeiten (multiplexing mit socket_select() )
das grundgerüst für den server hab ich hier her
http://de2.php.net/manual/de/function.socket-select.php#56241
das ist auch fast fertig, aber es tritt ein fehler auf den ich mir auch
nach langem debuggen nicht erklären kann.
das problem tritt auf wenn sich ein client beendet.
socket_select() gibt dann bescheid, dass sich etwas geändert hat.
nun sollte bei socket_read() FALSE zurück kommen (laut doku). es wird
aber ein leerstring zurückgegeben.
socket_select() kehrt direkt zurück und damit hat man eine ungebremste
unendlich-schleife.
ich könnte auch nach leerstring filtern, aber wenn dann ein client
wirklich mal nen leerstring sendet wird er gleich rausgeworfen.
ich hab mir das ganze mal mit netstat angesehen, der client bleibt mit
FIN_WAIT2 und der server mit CLOSE_WAIT stehen.
also müsste der server auf den socket_shutdown() des client mir einem
eigenen socket_shutdown() reagieren, aber ich weiß nicht wie man den
abfängt.
ich arbeite unter Ubuntu 8.10 (lammp)
hier die beiden codes
<?php
// --- Server ---
$port = 62135;
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($sock, '127.0.0.1', $port);
socket_listen($sock);
$clients = array($sock);
while (true)
{
$read = $clients;
if (socket_select($read, $write = NULL, $except = NULL, 0, 15000)
< 1) continue;
if (in_array($sock, $read))
{
$clients[] = $newsock = socket_accept($sock);
socket_write($newsock, "welcome\n"."There are ".(count
($clients) - 1)." client(s) connected to the server\n");
socket_getpeername($newsock, $ip);
echo "New client connected: {$ip}\n";
$key = array_search($sock, $read);
unset($read[$key]);
}
foreach ($read as $read_sock)
{
$data = @socket_read($read_sock, 1024, PHP_BINARY_READ);
if ($data === false)
{
$key = array_search($read_sock, $clients);
unset($clients[$key]);
echo "client disconnected.\n";
continue;
}
$data = trim($data);
if (!empty($data))
{
foreach ($clients as $send_sock)
{
if ($send_sock != $sock)
{
echo $data."\n";
socket_write($send_sock, '>'.
$data."\n");
}
}
}
}
}
socket_shutdown($sock, 2);
socket_close($sock);
?>
<?
// --- Client ---
$port = 62135;
$stdin = fopen('php://stdin','r');
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
@socket_connect($sock, '127.0.0.1', $port) or die('connection fault');
socket_set_nonblock($sock);
while(true)
{
socket_select($read = array($sock), $write = NULL, $except =
NULL, 0,15000);
if(in_array($sock,$read)) echo socket_read($sock, 2048,
PHP_BINARY_READ);
$x = fgets ($stdin, 2048);
if(substr($x,0,4) == 'quit') break;
socket_write ($sock, $x);
}
socket_shutdown($sock, 2);
socket_close($sock);
?>
Bitte helft mir ... :(
MfG janismac