Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> socket_write i sockety, sprawdzenie czy wysłany ciąg dotarł do klienta
DzikiLis
post 4.11.2007, 13:18:58
Post #1





Grupa: Zarejestrowani
Postów: 36
Pomógł: 0
Dołączył: 16.12.2005
Skąd: Warszawa, Kabaty

Ostrzeżenie: (0%)
-----


Cześć,

Piszę w PHP prosty serwer działający po socketach. Schemat działania jest prosty:
1) klient wysyła ciąg znaków z komendą,
2) serwer odbiera ciąg,
3) serwer "myśli" przez kilkanaście-kilkadziesiąt sekund,
4) serwer wysyła odpowiedź,
5) klient odbiera odpowiedź i zamyka połączenie.

Sęk w tym, że mielenie w punkcie trzecim może trwać dowolnie długo i klient może w międzyczasie zamknąć połączenie, a odpowiedź zostanie wysłana na zamknięty port. Zgodnie z manualem funkcja socket_write() powinna zwrócić false w przypadku, gdy nie doszło do zapisania. Niestety, nigdy nie zwraca false, nawet jeśli klient w międzyczasie przerwie połączenie.

Wymyśliłem obejście z funkcją socket_shutdown, ale to wymusza schemat: jedno połączenie, jedno zapytanie, jedna odpowiedź. Może ktoś ma pomysł co z tym fantem zrobić?

  1. #!/usr/bin/php -q
  2. <?php
  3. $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  4. socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
  5. socket_bind($sock, '12.34.56.789', 10000);
  6. socket_listen($sock);
  7. $clients = array($sock);
  8. while (true) {
  9. $read = $clients;
  10. if (socket_select($read, $write = null, $except = null, 0) < 1) continue;
  11. if (in_array($sock, $read))
  12. {
  13. $clients[] = $newsock = socket_accept($sock);
  14. socket_getpeername($newsock, $ip);
  15. echo "New client connected: {$ip}r\n";
  16. $key = array_search($sock, $read);
  17. unset($read[$key]);
  18. }
  19. foreach ($read as $j => $read_sock)
  20. {
  21. $data = @socket_read($read_sock, 1024, PHP_NORMAL_READ);
  22. if ($data === false) {
  23. $key = array_search($read_sock, $clients);
  24. unset($clients[$key]);
  25. echo "Client disconnected.r\n";
  26. continue;
  27. }
  28. $data = trim($data);
  29. if (!empty($data))
  30. {
  31. if ($data == 'mielenie') sleep(30);
  32. // i tutaj pojawia się problem, bo socket_write nie zwraca błędu nawet jeśli połączenie zostanie przerwane
  33. if (@socket_write($read_sock, $data."\n") !== false)
  34. {
  35. echo "Sent {$data}r\n";
  36. // działa natomiast ręczne zamknięcie socketa, ale też nie zawsze (NAT).
  37. if (@socket_shutdown($read_sock) !== false)
  38. {
  39. echo "Shutdown ok {$data}r\n";
  40. }
  41. else 
  42. {
  43. echo "Shutdown error {$data}r\n";
  44. }
  45. }
  46. else 
  47. {
  48. echo "Error {$data}r\n";
  49. }
  50. }
  51. }
  52. }
  53. socket_close($sock);
  54. ?>


Ten post edytował DzikiLis 4.11.2007, 13:22:21
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 18.07.2025 - 02:59