PHP: listen na UDP porte

Programovacie jazyky, rady, poradňa...
Mek
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4661
Registrovaný: 23 mar 2005, 23:00
Bydlisko: ZA <-> TN
Kontaktovať používateľa:

PHP: listen na UDP porte

Príspevok od používateľa Mek »

Tak som tu tentokrat s takym exotickejsim problemikom :)
Co chcem urobit, je, nacuvat na porte UDP/65136, pockat 5s na prichadzajuce data a tieto data zobrazit.

Kód: Vybrať všetko

$port = 65136;

	$timeout=time();
	while (time()<$timeout+5) // wait 5s for response
	{
$socketD = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); // create an UDP socket
   if($socketD === FALSE) { //omg, something went wrong
       echo 'socket_create failed: '.socket_strerror(socket_last_error())."\n";
       exit(1);
   }
  
	if (!socket_set_option($socketD, SOL_SOCKET, SO_REUSEADDR, 1)) {
		echo 'Unable to set option on socket: '. socket_strerror(socket_last_error())."\n";
	}

   if(!socket_bind($socketD, '0.0.0.0', $port)) {
       socket_close($socketD);
       echo 'socket_bind failed: '.socket_strerror(socket_last_error())."\n";
       exit(1);
   }
   // so far, our socket is open and bound to a port: it's listening for ONE incoming connection
	socket_set_nonblock($socketD);
   // this is a special way of socket_read()'ing what's on the socket once someone establishes a connection
  $len=socket_recvfrom($socketD, $buf, 2048, 0, $clientIP, $clientPort);
  echo $len.' bytes received from '.$clientIP.':'.$clientPort.'<br>';
	flush();
    if($buf === FALSE) { // something went wrong
       echo 'socket_read() returned false : '.socket_strerror(socket_last_error())."\n";
       continue;
   } elseif(strlen($buf) === 0) { // this should mean "client closed the connection"
       echo 'socket_read() returned an empty string : '.socket_strerror(socket_last_error())."\n";
       continue;
   } else echo $buf.'<br>';
	flush();
	socket_shutdown($socketD,2);
	socket_close($socketD);
		usleep(100000);
	}

Tento kod som okopcil z netu, ale funguje tak, ze v tom cykle hadze warningy:
Warning: socket_recvfrom() [function.socket-recvfrom]: unable to recvfrom [11]: Resource temporarily unavailable in /srv/web/virtuals/tranceworld.cz/www/dcsearch/index.php on line 160
a na konci
Warning: socket_shutdown() [function.socket-shutdown]: unable to shutdown socket [107]: Transport endpoint is not connected in /srv/web/virtuals/tranceworld.cz/www/dcsearch/index.php on line 173
To, ze endpoint is not connected by som este pochopil (UDP je nespojovo orientovany), ale co to znamena ze Resource temporarily unavailable... nemam sajnu, preco je vlastne docasne nedostupny.
Btw. musi to byt UDP, lebo tak je specifikovany protokol, s ktorym sa snazim pracovat. S TCP som skusal urobit jednoduchy skript, ktory vypisoval to, co som napisal cez telnet a to fungovalo :) akurat tu s tymto UDP si neviem rady.
Skusal som aj namiesto recvfrom pouzit socket_read(), ale to tiez nefungovalo. Ma niekto skusenosti?
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

To prvé upozornenie ti píše preto, lebo nie sú dostupné žiadne údaje. Keby si nenastavil, že je to neblokujúci socket, tak by sa to upozornenie nevypísalo (namiesto toho upozornenia by sa to tam zablokovalo).
Mek
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4661
Registrovaný: 23 mar 2005, 23:00
Bydlisko: ZA <-> TN
Kontaktovať používateľa:

Príspevok od používateľa Mek »

Ano ano, ked bol blocking (defaultne), tak sa na tom poveli skript zastavil a cakal donekonecna. Znamena to teda, ze vobec ziadne data neprisli? :?
Ok a ako teda spravit, ze ak ziadne data nepridu, tak nech to po 5s vzda, aby to tam neviselo vecnost :?:
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Kód: Vybrať všetko

<?php
$port = 65136;

$socketD = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if($socketD === FALSE) {
	echo 'socket_create failed: '.socket_strerror(socket_last_error())."\n";
	exit(1);
}

if (!socket_set_option($socketD, SOL_SOCKET, SO_REUSEADDR, 1)) {
	echo 'Unable to set option on socket: '. socket_strerror(socket_last_error())."\n";
}

if(!socket_bind($socketD, '0.0.0.0', $port)) {
	socket_close($socketD);
	echo 'socket_bind failed: '.socket_strerror(socket_last_error())."\n";
	exit(1);
}

while (true) {
	$empty = NULL;
	$read = array($socketD);
	$count = socket_select($read, $empty, $empty, 5);
	if ($count === false) {
		echo 'socket_select() returned false : '.socket_strerror(socket_last_error())."\n";
		break;
	}
	if ($count == 0) {
		echo "timeout\n";
		break;
	}
	for ($i = 0; $i < $count; $i++) {
		$len=socket_recvfrom($read[$i], $buf, 2048, 0, $clientIP, $clientPort);
		echo $len.' bytes received from '.$clientIP.':'.$clientPort.'<br>';
		flush();
		if($buf === FALSE) {
			echo 'socket_read() returned false : '.socket_strerror(socket_last_error())."\n";
			break;
		} elseif(strlen($buf) === 0) {
			echo 'socket_read() returned an empty string : '.socket_strerror(socket_last_error())."\n";
		} else echo $buf.'<br>';
	}
	flush();
	usleep(100000);
}

socket_close($socketD);
?>
Mek
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4661
Registrovaný: 23 mar 2005, 23:00
Bydlisko: ZA <-> TN
Kontaktovať používateľa:

Príspevok od používateľa Mek »

JO diky chrono, s mensimi upravami to konecne funguje tak, ako ma :D
(vidiet, ze sa vyznas, ka+ je tvoja)
Napísať odpoveď