Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> socket_write i sockety, sprawdzenie czy wysłany ciąg dotarł do klienta
DzikiLis
post
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
 
Start new topic
Odpowiedzi
rolnix
post
Post #2





Grupa: Zarejestrowani
Postów: 115
Pomógł: 0
Dołączył: 16.04.2005
Skąd: Białowieża

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


Uruchomienie programu napisanego w c++ to dodatkowe koszta? Człowieku, przecież i tak chcesz ten skrypt uruchamiać z shella. Co jest szybsze - interpretowanie i działanie skryptu czy działanie bezpośrednio kodu binarnego?

Może i przepisanie tego do C++ zajmie więcej czasu... ale napisałeś "po to by chodziło szybciej". Radziłbym bardziej zrobić tak, żeby w ogóle chodziło (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Ten post edytował rolnix 4.11.2007, 18:58:12
Go to the top of the page
+Quote Post
DzikiLis
post
Post #3





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

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


Cytat(rolnix @ 4.11.2007, 18:57:02 ) *
Uruchomienie programu napisanego w c++ to dodatkowe koszta? Człowieku, przecież i tak chcesz ten skrypt uruchamiać z shella. Co jest szybsze - interpretowanie i działanie skryptu czy działanie bezpośrednio kodu binarnego?

Szybkość działania skryptu nie ma tutaj większego znaczenia. Liczba połączeń jest szacowana na 100 dziennie, potem sie może rozkręcić, jeśli klienci końcowi będą korzystać z oferowanej usługi przez ten kanał. Ale ok: szybsze w działaniu - C++, tańsze dla klienta - PHP. Przeliczyć na głos? Dopisanie serwera po socketach w PHP zajmie ~20 godzin, napisanie serwera w C++ i logiki mielącej (działającej tak samo ja ta z PHP) zajmie dobremu programiście C++ min. 100 godzin (cała logika PHP zajęła > 1200h). A, klient chce ruszać za dwa tygodnie, a nie mamy w zespole dobrego programisty C++. Którą opcję wybrałbyś na miejscu klienta?
Go to the top of the page
+Quote Post

Posty w temacie


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

 



RSS Aktualny czas: 8.10.2025 - 11:47