Avatar billede toppus Nybegynder
21. marts 2005 - 22:23 Der er 16 kommentarer og
1 løsning

Lytte på UDP port

Nogle der ved hvordan man henter data som bliver sendt til min PC via udp, jeg har forsøgt med dette men der sker ikke noget.
Via en sniffer kan jeg se af pakkerne vælter ind i ren tekst.

<?php
$fp = stream_socket_client("udp://127.0.0.1:29700", $errno, $errstr);
if (!$fp) {
    echo "ERROR: $errno - $errstr<br />\n";
} else {
    fwrite($fp, "\n");
    echo fread($fp, 26);
    fclose($fp);
}
?>
Avatar billede rednex Nybegynder
21. marts 2005 - 22:50 #1
Da du skal lytte efter data skal du ikke bruge en klient men en server. Der er faktisk et eksempel på en UDP server i PHP manualen.

http://dk.php.net/manual/en/function.stream-socket-server.php
Avatar billede toppus Nybegynder
21. marts 2005 - 23:18 #2
Nu har jeg prøvet dette, men der sker heller ingen ting...
Hvad er der så galt ???

<?php
$socket = stream_socket_server("udp://127.0.0.1:29700", $errno, $errstr, STREAM_SERVER_BIND);
if (!$socket) {
  die("$errstr ($errno)");
}

do {
  $pkt = stream_socket_recvfrom($socket, 1, 0, $peer);
  echo "$peer\n";
  stream_socket_sendto($socket, date("D M j H:i:s Y\r\n"), 0, $peer);
} while ($pkt !== false);

?>
Avatar billede rednex Nybegynder
22. marts 2005 - 08:05 #3
Husk at stream_socket_xxx kun virker under PHP5. Hvis du kører med tidligere versioner af PHP skal du bruge "gammeldaws" sockets. Desuden skal serverdelen ikke køres som et script under webserveren, men i stedet køres i command-line interfacet. Ellers vil serverdelen blive lukket ned efter 30 sekunder (eller hvad du nu har sat script timeout til).
Avatar billede toppus Nybegynder
22. marts 2005 - 11:14 #4
Øhhh  ved ikke hvilke ver  php jeg kører med
Hvordan ville "gammelsdags" socket se ud... kan du gi' et eks.
Avatar billede toppus Nybegynder
22. marts 2005 - 11:37 #5
Nu har jeg opgraderet til ver 5, men ... det virker ikke rigtig.. Hvordan kommer jeg til commandline ??
Avatar billede rednex Nybegynder
22. marts 2005 - 11:53 #6
Jeg går ud fra at du kører Windows. Så åbner du en kommandoprompt ved at trykke start->kør... her skriver du cmd.exe og trykker OK. Skift hen til den mappe dit script ligger i, f.eks. "cd c:\web\php" (uden gåseøjne). Hvis scriptet ligger på et andet drev skal du skifte til det drev. Hvis det ligger på D: skriver du "d:".

For at køre scriptet skriver du "<sti til php>\php.exe <scriptnavn>". F.eks. "C:\php\php.exe udpserver.php".

Jeg har prøvet serverscriptet fra php.net og det kører fint på PHP5. Jeg brugte eksemplet fra stream_socket_client til at connecte til serveren. Klienten kan bruges via webserveren.
Avatar billede toppus Nybegynder
22. marts 2005 - 14:42 #7
Nu er det lykkes mig af få kontakt til porten via dette script, men det viser IKKE hvad der bliver sendt til porten..

<?php
// example of "daemon" in UDP
while(TRUE) { // never stop the daemon
  $socketD = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); // create an UDP socket

  echo 'Creating socket... '; // YES, the socket is creating EACH TIME the while loops
 
  if($socketD === FALSE) { //omg, something went wrong
      echo 'socket_create failed: '.socket_strerror(socket_last_error())."\n";
      exit(1);
  }
 
  echo "OK\nBinding the socket on 0.0.0.0:27500 ... ";
  // let the daemon listen on the port 27500 on all interfaces
  if(!socket_bind($socketD, "0.0.0.0", 27500)) {
      socket_close($socketD);
      echo 'socket_bind failed: '.socket_strerror(socket_last_error())."\n";
      exit(1);
  }
 
  echo "OK\nNow ready to accept connections.\nListening on the socket ... \n";
  // so far, our socket is open and bound to a port: it's listening for ONE incoming connection

  // this is a special way of socket_read()'ing what's on the socket once someone establishes a connection
  socket_recvfrom($socketD, $buf, 65535, 0, $clientIP, $clientPort);
  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;
  }

  echo 'Incoming connection from '.$clientIP.':'.$clientPort.' ... ';

  // ok now thats the tricky part
  // if you want to reply to the client on the UDP socket it opened, you need to connect your listening socket on them
  // this won't work unless the client puts their IP in the IP  header of the packets it's sending to your socket
  // UDP sessions don't require them to do so, and if they don't, you have no way to tell who's talking to you on the socket, and therefore no way to reply
  // so if you want to interact with the client, you have to connect your socket on them, but by doing so, you're no longer listening to other incoming connections
  // one way to fixe that would be to fork the script when an incoming connection arrives and then stop the forked script once the client exits
  if(!socket_connect($socketD, $clientIP, $clientPort)) {
      echo 'socket_create failed to connect the clientsock on '.$clientIP.':'.$clientPort.' : '.socket_strerror(socket_last_error())."\n";
      socket_close($socketD);
      continue;
  }
  echo 'connected'."\n"; // cool, now we can reply to the client

  // now you can interact with the client using socket_write() and socket_read()

  // once you're finished, you need to socket_close() your sockets and let the while loop and re-create the listenning socket (because you're no longer listenning for new incoming connections)
} // end of the infinite while
?>
Avatar billede rednex Nybegynder
22. marts 2005 - 15:04 #8
Jeg faldt lige over dit spm i ASP kategorien, så nu har jeg en idé om hvad du skal bruge det til. Jeg går ikke ud fra at din CS server skal have svar, så dette script nøjes med at logge den trafik der kommer til en fil.

<?php
$ip = '0.0.0.0'; // Lytter på alle maskinens IPer
$port = 27500;
$filename = "log.txt";

$fp = @fopen($filename, 'a');
if(!$fp)
    die('failed to open log file!');

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if(!$socket)
    die('socket_create failed: ' . socket_strerror(socket_last_error()) . "\n");

if(!socket_bind($socket, $ip, $port)) {
    socket_close($socket);
    die('socket_bind failed: '.socket_strerror(socket_last_error())."\n");
}

do {
    socket_recvfrom($socket, $pkt, 2048, 0, $clientIP, $clientPort);
    $log = '[' . date("d/m-Y H:i:s") . "] $clientIP:$clientPort: $pkt\r\n";
    echo $log;
    fwrite($fp, $log);
} while ($pkt !== false);

socket_close($socket);
fclose($fp);

?>
Avatar billede toppus Nybegynder
22. marts 2005 - 16:53 #9
Det er bare helt kanon.... Hvis jeg kører det via command-line interfacet så gør den det den skal, men er der en mulighed for af få vist det "live" i browseren, sådan så hvis siden opdater hver 5 sec så tømmer den bufferen og viser det på siden ??
Avatar billede rednex Nybegynder
22. marts 2005 - 16:58 #10
Du er nødt til at køre serveren separat da den er nødt til at lytte efter UDP pakker hele tiden. Men du kan jo lave et webinterface som læser logfilen og refresher hvert 5. sekund.
Avatar billede toppus Nybegynder
22. marts 2005 - 17:09 #11
Ja det er self. en mulighed :)... Du skal mange tak for din hjælp, jeg er blevet MEGET klogere på både PHP og UDP.
Avatar billede toppus Nybegynder
22. marts 2005 - 17:12 #12
Øhh lige et hurtigt spørgsmål.... I asp kan man lave    test=replace(test, "A", "B")  Hvordan laves det i PHP?
Avatar billede rednex Nybegynder
22. marts 2005 - 17:15 #13
Man kan ikke andet end at blive vild med PHP når man først kommer igang. Jeg har selv programmeret ASP tidligere, men skiftede til PHP da jeg fandt ud af hvor flexibelt det var. Der er jo stort set ikke den ting der ikke kan laves out-of-the-box i modsætning til ASP hvor man er nødt til at installere nye COM-objekter på serveren hver gang man skal lave andet end en if-sætning.
Avatar billede rednex Nybegynder
22. marts 2005 - 17:16 #14
$test = str_replace('a', 'b', $test);
Avatar billede toppus Nybegynder
22. marts 2005 - 17:30 #15
ja.. Det er jo lige det der er problemet med ASP, men syntes det er svært af kommer igang med PHP.. Det er en anden verden :)  og endnu engang tak for hjælpen
Avatar billede rednex Nybegynder
22. marts 2005 - 17:37 #16
Det var så lidt, og husk lige at lukke spørgsmålet :o)

Det er altid svært at skifte sprog, men øvelse gør jo som bekendt mester. Du kan som regel finde gode eksempler på de fleste funktioner i PHP manualen, så det hjælper jo lidt. Samtidig er manualen opdelt efter funktion (f.eks. MySQL funktioner, sockets osv.) så det er nemt at finde de ting man skal bruge.
Avatar billede toppus Nybegynder
22. marts 2005 - 17:51 #17
jeg vil gøre et forsøg, da jeg kan se en kæmpe fordel
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester