Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PHP TCP Server und Client

12 views
Skip to first unread message

janismac

unread,
Dec 3, 2008, 10:16:54 AM12/3/08
to
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

janismac

unread,
Dec 6, 2008, 12:54:55 PM12/6/08
to
[gelöst]

Joerg Behrens

unread,
Dec 6, 2008, 4:09:48 PM12/6/08
to
janismac schrieb:
> [gelöst]

Na prima.... magst du uns auch die Loesung veraten?

Gruss
Joerg

janismac

unread,
Dec 11, 2008, 3:31:02 PM12/11/08
to
ich habe bei client und server:

- select() ohne timeout (=> NULL) verwendet
- den socket nicht auf nonblock gestellt
- read() mit PHP_NORMAL_READ verwendet

und dann den rest entsprechend umgeschrieben (sollte in den meisten
fällen möglich sein)

MfG janismac

PS: irgendwas ist an dieser NG seltsam, bei mir verschwinden die header
des öfteren - muss sie immer neu laden.

0 new messages