Toon posts:

[PHP] Script hangt bij het gebruik van sockets ( ping )

Pagina: 1
Acties:
  • 56 views sinds 30-01-2008

Verwijderd

Topicstarter
Ik gebruik volgend stukje code om te pingen naar verschillende pda toestellen die wij in het bedrijf in gebruik hebben om te zien of de toestellen aangelogt zijn op het netwerk :


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php

class Net_Ping
{
  var $icmp_socket;
  var $request;
  var $request_len;
  var $reply;
  var $errstr;
  var $time;
  var $timer_start_time;
  function Net_Ping()
  {
   $this->icmp_socket = socket_create(AF_INET, SOCK_RAW, 1);
   socket_set_block($this->icmp_socket);
  }
  
  function ip_checksum($data)
  {
     for($i=0;$i<strlen($data);$i += 2)
     {
         if($data[$i+1]) $bits = unpack('n*',$data[$i].$data[$i+1]);
         else $bits = unpack('C*',$data[$i]);
         $sum += $bits[1];
     }
     
     while ($sum>>16) $sum = ($sum & 0xffff) + ($sum >> 16);
     $checksum = pack('n1',~$sum);
     return $checksum;
  }

  function start_time()
  {
   $this->timer_start_time = microtime();
  }
  
  function get_time($acc=2)
  {
   // format start time
   $start_time = explode (" ", $this->timer_start_time);
   $start_time = $start_time[1] + $start_time[0];
   // get and format end time
   $end_time = explode (" ", microtime());
   $end_time = $end_time[1] + $end_time[0];
   return number_format ($end_time - $start_time, $acc);
  }

  function Build_Packet()
  {
   $data = "abcdefghijklmnopqrstuvwabcdefghi"; // the actual test data
   $type = "\x08"; // 8 echo message; 0 echo reply message
   $code = "\x00"; // always 0 for this program
   $chksm = "\x00\x00"; // generate checksum for icmp request
   $id = "\x00\x00"; // we will have to work with this later
   $sqn = "\x00\x00"; // we will have to work with this later

   // now we need to change the checksum to the real checksum
   $chksm = $this->ip_checksum($type.$code.$chksm.$id.$sqn.$data);

   // now lets build the actual icmp packet
   $this->request = $type.$code.$chksm.$id.$sqn.$data;
   $this->request_len = strlen($this->request);
  }
  
  function Ping($dst_addr,$timeout=5,$percision=3)
  {
   // lets catch dumb people
   if ((int)$timeout <= 0) $timeout=5;
   if ((int)$percision <= 0) $percision=3;
   
   // set the timeout
   socket_set_option($this->icmp_socket,
     SOL_SOCKET,  // socket level
     SO_RCVTIMEO, // timeout option
     array(
       "sec"=>$timeout, // Timeout in seconds
       "usec"=>0  // I assume timeout in microseconds
       )
     );

   if ($dst_addr)
   {
     if (@socket_connect($this->icmp_socket, $dst_addr, NULL))
     {
     
     } else {
       $this->errstr = "Cannot connect to $dst_addr";
       return FALSE;
     }
     $this->Build_Packet();
     $this->start_time();
     socket_write($this->icmp_socket, $this->request, $this->request_len);
     if (@socket_recv($this->icmp_socket, &$this->reply, 256, 0))
     {
       $this->time = $this->get_time($percision);
       return $this->time;
     } else {
       $this->errstr = "Timed out";
       return FALSE;
     }
   } else {
     $this->errstr = "Destination address not specified";
     return FALSE;
   }
  }
}

$ping = new Net_Ping;
$ping->ping("10.1.10.5",2);

if ($ping->time)
  echo "Time: ".$ping->time;
else
  echo $ping->errstr;

?>


De code werkt perfect voor enkele opvragingen, als ik dit echt in een lus programmeer komt het script vast te zitten en dit op op de lijn waar de instructie socket_recv wordt uitgevoerd.

Als ik de @ wegneem krijg ik volgende fout te zien : "Fatal error: Maximum execution time of 30 seconds exceeded in C:\Inetpub\wwwroot\test\ping\ping.php on line 97" en dit na 11 pogingen naar hetzelfde adres.

De set_time_limit wil ik niet aanpassen, ik zou willen dat ik bijvoorbeeld 20 verschillende adressen kan pingen.

Ik heb al geprobeerd om de sockets telkens te sluiten maar dit bied geen oplossing.

  • xiD
  • Registratie: Oktober 2003
  • Laatst online: 20:00

xiD

12345

[workaround]
Je zou bijvoorbeeld het script dat pingt op de achtergrond kunnen laten draaien; doormiddel van een cronjob (linux) elke 2 minuten laten uitvoeren of iets dergelijks. En de resultaten daarvan in een database laten opslaan.

En een aparte pagina maken die de resulaten vanuit een database op het scherm laat zien. Die pagina blijft dan gewoon snel.
[/workaround]

67890


  • IntToStr
  • Registratie: December 2003
  • Laatst online: 22:14
Je zit met de maximum execution time voor een script van php. Zoals hierboven al wordt aangegeven kun je dit script ook met een cronjob of zo aanroepen. Je kunt altijd nog de waarde voor die execution time wijzigen in php.ini of met een ini_set, maar dat lijkt me ook niet echt ideaal in dit geval :)

offtopic:
En percision??

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 30-11 15:10

Creepy

Tactical Espionage Splatterer

Je zult de time_limit moeten aanpassen/omzeilen of niet vanuit je script in een loop moeten gaan pingen. Andere oplossingen zijn er gewoon niet.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
Bedankt voor de info, probleem is inderdaad opgelost met de limit aan te passen, topic mag gesloten worden.

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
De time limit aanpassen is niet echt een oplossing, eerder een workaround. (Eentje die overigens desastreus kan zijn als er nog andere applicaties op je webserver draaien die wel eens hangen.) Bovendien krijg je straks weer problemen als je weer een X aantal PDA's erbij krijgt om te pingen...

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Een slotje is niet nodig op een topic als je je oplossing hebt. Zie daarvoor ook onze faq betreffende topiceinde. ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Grijze Vos schreef op maandag 04 juni 2007 @ 10:07:
De time limit aanpassen is niet echt een oplossing, eerder een workaround. (Eentje die overigens desastreus kan zijn als er nog andere applicaties op je webserver draaien die wel eens hangen.) Bovendien krijg je straks weer problemen als je weer een X aantal PDA's erbij krijgt om te pingen...
Je moet die time limit ook alleen voor die ene applicatie aanpassen (en dat kan runtime). Zet die op unlimited en je hebt ook geen probleem bij meerdere PDA's. (hoewel een service/cronjob hier handiger voor is imo)

  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 00:19
Ik snap er niets meer van???

Hier gebruik je het zelfde script, en krijg je problemen met raw sockets. Of draait dit script niet onder 2003?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
En nu heb ik deze topics wel genoeg gezien.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Pagina: 1

Dit topic is gesloten.