Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Mój pierwszy serwer w PHP...
Próbowałeś/aś napisać własny serwer w PHP?
Próbowałeś/aś napisać własny serwer w PHP?
Tak [ 8 ] ** [12.70%]
Nie [ 52 ] ** [82.54%]
Próbowałem/am, ale mi nie wyszło... [ 3 ] ** [4.76%]
Suma głosów: 40
Goście nie mogą głosować 
Bakus
post 15.12.2003, 05:16:43
Post #1


Administrator serwera


Grupa: Przyjaciele php.pl
Postów: 909
Pomógł: 0
Dołączył: 12.08.2003
Skąd: /var/www/wroclaw.php

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


Serwer (Wywoływany jako "php -q serwer.php"):
  1. <?php
  2. if(!extension_loaded('sockets'))
  3. dl(&#092;"php_sockets.dll\");
  4.  
  5. error_reporting (E_ALL);
  6.  
  7. $address = '192.168.0.1';
  8. $port = 522;
  9.  
  10. print 'Uruchamianie serwera';
  11.  
  12. if (($sock = socket_create(AF_INET, SOCK_STREAM, 0)) < 0)
  13. echo &#092;"nnsocket_create() failed: reason: \" . socket_strerror ($sock) . \"n\"; else print '.';
  14.  
  15. if (($ret = socket_bind($sock, $address, $port)) < 0)
  16. echo &#092;"nnsocket_bind() failed: reason: \" . socket_strerror($ret) . \"n\"; else print '.';
  17.  
  18. if (($ret = socket_listen($sock, 5)) < 0)
  19. echo &#092;"nnsocket_listen() failed: reason: \" . socket_strerror($ret) . \"n\"; else print '.';
  20.  
  21. do{
  22. if (($msgsock = socket_accept($sock)) < 0)
  23. {
  24. echo &#092;"nnsocket_accept() failed: reason: \" . socket_strerror($msgsock) . \"n\";
  25. break;
  26. }
  27.  
  28. $msg = &#092;"nWelcome to the KAB php Test Server. n\";
  29. socket_write($msgsock, $msg, strlen($msg));
  30. print &#092;"tUser connected\";
  31.  
  32. do{
  33. if (FALSE === ($buf = socket_read ($msgsock, 4096, PHP_NORMAL_READ)))
  34. {
  35. echo &#092;"socket_read() failed: reason: \" . socket_strerror($ret) . \"n\";
  36. break 2;
  37. }
  38. if (!$buf = trim($buf))
  39. {
  40. continue;
  41. }
  42. if ($buf == 'quit')
  43. {
  44. break;
  45. }
  46. if ($buf == 'get')
  47. {
  48. print &#092;"nttWysylanie 'file'...n\";
  49. $message = 'file';
  50. socket_write($msgsock, $message, strlen($message));
  51. print &#092;"ttreadyn\";
  52. if(!(FALSE === ($b = socket_read ($msgsock, 4096, PHP_NORMAL_READ))))
  53. {
  54. $message = 'ok';
  55. socket_write($msgsock, $message, strlen($message));
  56. $f = fopen(&#092;"./\" . $b, \"wb\");
  57. print &#092;"ttTransfering data\";
  58. while(!(FALSE === ($b = socket_read ($msgsock, 10240, PHP_NORMAL_READ))))
  59. {
  60. if($b != &#092;"end\")
  61. {
  62. print '.';
  63. fwrite($f, base64_decode($B));
  64. }else{
  65. print &#092;"nttOtrzymano 'end'...n\";
  66. fclose($f);
  67. break 2;
  68. }
  69. }
  70. print &#092;"tendn\";
  71. }else{
  72. print &#092;"terrorn\";
  73. }
  74. }
  75. if ($buf == 'shutdown')
  76. {
  77. $quit_message = 'Dziękujemy za skorzystanie z naszych usług';
  78. socket_write($msgsock, $quit_message, strlen($quit_message));
  79. socket_close($msgsock);
  80. print 'Zatrzymywanie serwera';
  81. break 2;
  82. }
  83. $talkback = &#092;"> '$buf'.n\";
  84. socket_write($msgsock, $talkback, strlen($talkback));
  85. echo &#092;"$bufn\";
  86. }while(true);
  87. print &#092;"tUzytkownik rozlaczonynn\";
  88. print &#092;"Oczekiwanie na nastepne polaczenien\";
  89. socket_close ($msgsock);
  90. }while(true);
  91. socket_close ($sock);
  92.  
  93. print &#092;"...EOSnn\";
  94. ?>


Klient (przez www):
  1. <PRE><?php
  2. $plik = &#092;"do_przeslania.zip\";
  3. $sciezka = &#092;"./\";
  4.  
  5. $s = fsockopen('192.168.0.1', 522, $error, $errno, 10);
  6. print fread($s, 2048);
  7. fputs($s, 'get');
  8. if(fread($s, 2048) == &#092;"file\")
  9. {
  10. fputs($s, $plik);
  11. if(fread($s, 2048) == &#092;"ok\")
  12. {
  13. $fp = fopen($sciezka . $plik, &#092;"rb\");
  14. while (!feof($fp))
  15. {
  16. fputs($s, base64_encode(fgets($fp, 8196)));
  17. }
  18. fclose($fp);
  19. fputs($s, 'end');
  20. fputs($s, 'quit');
  21. fclose($s);
  22. }else{
  23. fputs($s, 'quit');
  24. fclose($s);
  25. }
  26. }else{
  27. fputs($s, 'quit');
  28. fclose($s);
  29. }
  30. ?></PRE>


Klient wysyła zawartość pliku odczytanego z dysku na serwer.
Serwer jest jednowątkowy piki co, ale jak na pierwsze moje dzieło z użyciem socket_* to chyba nieźle...

Byłbym wdzięczny za poprawki do tego wspaniałego (moim skromym zdaniem) serwera...
Klient będzie docelowo napisany w php-GTK, tak by odczytywać pliki z dysków użytkowników...

Celem jest stworzenie uploadera w php-GTK (klient) i php (serwer).

Klient tutaj zamieszczony jest (jak już wspomniałem) dla potrzeb testów...

Najbardziej liczę na waszą pomoc jeżeli chodzi o dodanie wielowątkowości do serwera - tak by naraz z niego mogło korzystać wiele osób.
Jeżeli okaże się to niemożliwe, to proszę o podpowiedź w jaki sposób można "zablokować" serwer przed kolejnymi uploadami (tak, by klient wiedziałm że serwer jest wykorzystywany przez kogoś innego i musi poczkać)

<b>Właśnie - najważniejsza sprawa - serwer jest pod windowsa!</b>
Nie mam zielonego pojęcia, czy i w jaki sposób będzie działał pod linuxem...

UpDated: malutki bug w kliencie - nazwy zmiennych
UpDated: dodanie "if mod loaded = false"...
Uaktualniłem BBCode do wersji z IPB...
winksmiley.jpg


--------------------
Powrót do przeszłości :)
Go to the top of the page
+Quote Post
Paul
post 15.12.2003, 19:42:13
Post #2





Grupa: Zarejestrowani
Postów: 636
Pomógł: 0
Dołączył: 22.10.2003
Skąd: Katowice

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


mozesz zrobic plik textowy w ktorym beda zapisalne info czy ktos teraz korzysta z uploadu - czyli na poczatku skryptu dajesz zapis do pliku, ze korzysta i na koncu po zakonczeniu uploadu ze jest skrypt wolny, plus jeszcze pare ifow, ze jak zawartosc danego pliku jest taka i taka to musisz czekac...
Go to the top of the page
+Quote Post
spenalzo
post 15.12.2003, 22:34:47
Post #3





Grupa: Zarejestrowani
Postów: 2 064
Pomógł: 1
Dołączył: 22.01.2003
Skąd: Poznań

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


Cytat
Jeżeli okaże się to niemożliwe, to proszę o podpowiedź w jaki sposób można "zablokować" serwer przed kolejnymi uploadami (tak, by klient wiedziałm że serwer jest wykorzystywany przez kogoś innego i musi poczkać)

Utwórz sobie pusty plik "busy" i jeżeli jest to znaczy, że serwer jest zajęty.

Hmmm... nie rozumiem po co pisać serwer w php... szczególnie jeżeli jest do przesyłu plików protokół php - ale nie żebym był przeciwny smile.gif


--------------------

Go to the top of the page
+Quote Post
adwol
post 16.12.2003, 00:27:28
Post #4





Grupa: Zarejestrowani
Postów: 691
Pomógł: 0
Dołączył: 6.08.2003

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


Cytat
Najbardziej liczę na waszą pomoc jeżeli chodzi o dodanie wielowątkowości do serwera - tak by naraz z niego mogło korzystać wiele osób.

Zainteresuj się funkcją socket_select. Nie daje to prawdziwej wielowątkowości (nie są tworzone osobne wątki ani procesy dla każdego requestu), ale pozwala na obsługę wielu połączeń w obrębie jednego procesu. Niestety php w wersji 4 na windows nie ma porządnego wsparcia do tworzenia wątków i procesów (o funkcjach exec i system nie mówimy). Rozszerzenie pctnl w którym jest funkcja pctnl_fork istnieje tylko w wersji uniksowej, więc z niej nie skorzystasz. Będziesz się musiał zadowolić praktyczne chyba tylko selectem.
Cytat
Właśnie - najważniejsza sprawa - serwer jest pod windowsa!Nie mam zielonego pojęcia, czy i w jaki sposób będzie działał pod linuxem...

Sockety pochodzą orygnialnie z uniksa (dokładniej z BSD) i uniksy są ich ojczyzną. Jeśli pracuje to prawidłowo na windowsie to na linuksie też nie będzie większych problemów. smile.gif

Z ogólnych uwag:
:arrow: Masz troche bałaganu w kodzie. Napisałeś to bez użycia chociażby jednej funkcjii, że o klasach nawet nie wspomnę.
:arrow: Ustal sobie najpierw jakiś protokół komunikacji (możesz bazować na HTTP). Wymyśl jak będzie przebiegała transmisja i komunikacja, jakie będą wydawane komendy, itp. Np. niech będą na początek dwie istotne komendy: GET i PUT (znaczenie wiadome). Parametry do tych komend (np. nazwy plików) staraj się dawać w jednej linii z komendą, np.:
Kod
GET plik.txt

Niech serwer odpowiada coś po każdym wysłanym żądaniu od klienta. Linie z odpowiedzią niech będą poprzedzane jakimś kodem statusu operacji. Będzie im wtedy łatwiej się ,,dogadać'' przy bardziej rozbudowanym protokole, reagować na błędy, itp. Np.: (S -- server, K -- klient)
Kod
S: 00 Witamy na naszym serwerze

K: GET /katalog/plik.txt

S: 10 Błąd. Plik /katalog/plik.txt nie istnieje.

K: GET /katalog/plik2.txt

S: 20 572

S: Pierwsza linia pliku

S: Druga linia pliku

S: Trzecia linia pliku

K: PUT /katalog/plik3.txt 1092

K: Pierwsza linia pliku

K: Druga linia pliku

K: Trzecia linia pliku

S: 30 Dziekuje. Odebrano 1092 bajty danych.

K: QUIT

S: 00 Do widzenia

Generalnie przewiduj rozszerzenie protokołu w przyszłości (chyba, że napewno tego nie chcesz) o np. autoryzacje, listowanie zawartości katalogów, itp. Łatwiej jest później dodać jeden nagłówek w żądaniu, niż przerabiać pół protokołu.
:arrow: Po co kodujesz wysyłane pliki za pomocą base64? Niech klient i serwer wysyłają przed początkiem transmisji długość pliku. W przyszłości być może przyda Ci się to do optymalizacji.
:arrow: Zapisz sobie obsługę każdej komendy jako osobną funkcję ze jednym stałym interfejsem do wszystkich. Główna pętla programu niech tylko obsługuje połączenia i rozdziela zadania pomiędzy funkcje

Możesz mieć problemy z efektywnym wykorzystaniem socket_select(), ale na początek spróbuj chociaż uzyskać wiele połączeń naraz (bez jednoczesnego wysyłania danych).

Dobrze, że ktoś się zainteresował innym wykorzystaniem php niż tylko jako język dynamicznych stron WWW, bo dla większości jest on nieodłącznie związany z tym segementem internetu. Niestety nie był on projektowany do takich zastosowań, ale przy odrobinie chęci da się z tego coś sensownego wykrzesać. winksmiley.jpg
Go to the top of the page
+Quote Post
Bakus
post 16.12.2003, 01:20:00
Post #5


Administrator serwera


Grupa: Przyjaciele php.pl
Postów: 909
Pomógł: 0
Dołączył: 12.08.2003
Skąd: /var/www/wroclaw.php

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


Dzięki adwol za opdpowiedź...
Napisałem to bez użycia funkcji/klas, ponieważ jest to "bardzo wczesna wersja alfa" winksmiley.jpg tego serwera...
Na dobrą sprawę byłem tak zadowolony, że serwer działa, że odrazu wrzuciłem kod na forum...
base64 zastosowałem ze względu na przesył danych binarnych przez które serwer się wywalał...

Właśnie implementuje obsługę komend...
Pomysł z wysyłaniem wielkości pliku jest wyjątkowo trafiony... smile.gif - miałem z tym problemy...

Co do [manual:c94fbfa6a5]socket_select[/manual:c94fbfa6a5] dopiero po zaimplementowaniu komend się tym szażej zainteresuje... szkoda, że manual jest po angielsku, jeżeli chodzi o ten wątek... sad.gif

Jeszcze raz dzięki...

@Paul i spenalzo: Dzięki za podpowiedź, ale chyba w gotowym serwerze wykorzystam rozwiązanie adwol'a... Jeszcze niewiem jak będzie działać, ale zapowiada się interesująco...

@spenalzo: Zawsze chciałem tworzyć programy (teraz już wiem, że są to "serwery"), które służyły by do przesyłania informacji przez sieć...

P.S. Wykorzystując silnik z tego serwera można napisać fajny serwerek chata dla np. sieci lokalnych w firmach...


--------------------
Powrót do przeszłości :)
Go to the top of the page
+Quote Post
Bakus
post 16.12.2003, 04:21:15
Post #6


Administrator serwera


Grupa: Przyjaciele php.pl
Postów: 909
Pomógł: 0
Dołączył: 12.08.2003
Skąd: /var/www/wroclaw.php

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


Komentarz na stronie manuala:

Cytat
Please note that the timeout parameter has important side-effects on the CPU usage of your script.

Setting the timeout to 0 will make your CPU looping without any time to have some rest and handle other running processes on your system, causing the system load to increase heavily while your script is running.


To chyba dyskwalifikuje funkcje dla zadania jakie mam jej powierzyć...


--------------------
Powrót do przeszłości :)
Go to the top of the page
+Quote Post
spenalzo
post 16.12.2003, 08:20:56
Post #7





Grupa: Zarejestrowani
Postów: 2 064
Pomógł: 1
Dołączył: 22.01.2003
Skąd: Poznań

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


No teraz, po tych postach widze, że jednak jest to ciekawy pomysł ...


--------------------

Go to the top of the page
+Quote Post
orson
post 16.12.2003, 10:12:29
Post #8





Grupa: Zarejestrowani
Postów: 548
Pomógł: 2
Dołączył: 19.07.2003

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


witam ...

w celu optymalizacji podpowiadam ze mozesz sie zainteresowac funkcjami kompresujacymi ... jezeli to sa dane binarne [ i sa raczej nie wielkie ... tak do 10 mb ] to chyba nie powinnno byc problemu ... i drugi tip dotyczy integralnosci danych ... dobrze by bylo robic md5 albo sha1 na pliku po stronie klienta i serwera ... takna wszeslki wypadek ...
pomysl fajny tylko interesuje mnie czy klient tylko w php-gtk questionmark.gif przez browser nie bedzie sie dalo ?

cya


--------------------
Computer games don't affect kids; I mean if <span style="font-weight: bold;">Pac Man</span> affected us as kids,we would all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music.
Go to the top of the page
+Quote Post
uboottd
post 16.12.2003, 11:33:16
Post #9





Grupa: Zarejestrowani
Postów: 384
Pomógł: 0
Dołączył: 3.04.2003
Skąd: Chorzow

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


Cytat
Komentarz na stronie manuala:

Cytat
Setting the timeout to 0 will make your CPU looping without any time to have some rest and handle other running processes on your system, causing the system load to increase heavily while your script is running.


To chyba dyskwalifikuje funkcje dla zadania jakie mam jej powierzyć...


Nie. Zakladam ze jest to komentarz do selecta. Timeout okresla czas po jakim ta funkcja odda ci sterowanie jesli nie przyjda zadne dane. Jesli jakies dane sie pojawia to wtedy zakonczy sie od razu jak te dane sie pojawia. O ile Twoj program nie musi czegos robic poza czekaniem na dane to timeout ustawia na nieskonczonosc.
Go to the top of the page
+Quote Post
Bakus
post 17.12.2003, 21:56:51
Post #10


Administrator serwera


Grupa: Przyjaciele php.pl
Postów: 909
Pomógł: 0
Dołączył: 12.08.2003
Skąd: /var/www/wroclaw.php

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


Po co pisać klienta w php - jako skrypt na WWW?
Można odrazu przesłać pliki na serwer przez zwykły upload...

W takim układzie pisanie serwer w php nie ma żadnego sensu...

Napisałem ten serwerek by ominąć ograniczenie uploadu i móc pobierać pliki więklsze od 2 MB z compa użytkownika.
Przy Kliencie - przeglądarce - musisz wysłać dane do serwera na którym php je dopiero przetworzy...
Ja pisząc klienta w php-GTK omijam przesyłanie plików na serwer przez protokół HTTP.
Poza tym co byś nie zrobił zwiększając wielkość "max_upload_size" w php.ini na więcej niż 2MB możesz zapchać serwer jeżeli stoi na kiepskim łączu... mój serwer korzysta z niezależnego pasma - nie obciąża Apacha i dzięki temu użytkownicy w dalszym ciągu mogą oglądać sobie stronki... wolniej, ale mogą... winksmiley.jpg

Cytat
mozesz sie zainteresowac funkcjami kompresujacymi
Rozmyślałem nad tym, ale jeszcze się zastanawiam...

Cytat
No teraz, po tych postach widze, że jednak jest to ciekawy pomysł ...
On od początku był ciekawy... winksmiley.jpg


--------------------
Powrót do przeszłości :)
Go to the top of the page
+Quote Post
klops
post 4.11.2005, 17:48:16
Post #11





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 5.04.2005

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


witam,
mam pare pytan odnosnie tego projektu bo wlasnie cos takiego potrzebuje - przesylanie plikow do i z serwera,
rozumiem ze klient musi chodzic na komputerze z interpreterem php? bez tego ani rusz?
a jesli powyzsze spelnione to wiem ze mozna jeszcze przesylac pliki za pomoca PUT i GET, ale z lektury tematu wywnioskowalem ze sa jakies ograniczenia odnosnie wielkosci przesylu, czy one wystepuja zawsze czy mozna dajmy na to przesylac nieograniczone ilosci danych? a jesli juz przeslemy dajmy na to pliczek na serwer to jak ze sie tak wyraze dostac do niego, tzn gdzie on jest zapisywany pod jaka nazwa itd?

pozdrawiam
Go to the top of the page
+Quote Post
Kocurro
post 4.11.2005, 20:00:06
Post #12





Grupa: Zarejestrowani
Postów: 461
Pomógł: 32
Dołączył: 17.09.2003
Skąd: Łódź

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


Bakus - limit uploadu możesz spokojnie ominąć innymi sposobami z o wiele ciekawszym efektem smile.gif
Go to the top of the page
+Quote Post
klops
post 5.11.2005, 19:27:16
Post #13





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 5.04.2005

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


a moglbys nieco rozwinac swoja wypowiedz:) bardzo mnie zainteresowales smile.gif i prosze o wiecej...
Go to the top of the page
+Quote Post
Kocurro
post 5.11.2005, 20:47:39
Post #14





Grupa: Zarejestrowani
Postów: 461
Pomógł: 32
Dołączył: 17.09.2003
Skąd: Łódź

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


Ja przeważnie omijałem to poprzez zmianę ustawień php w plikach htaccess, działało bez zarzutu.

Potem potrzebowałem skryptu by pokazać postęp w uploadzie. W tym pomogło mi sourceforge - tam znalazłem dobry pomysł + wykonanie jako cgi, potem poprzerabiałem i działa extra smile.gif

Wykorzystanie CGI daje jedną dodatkową cechę - zawsze można w jakiś sposób przekazać informacje by przerwać upload.

Ja na przykład zrobiłem w panelu administratora monitor uploadu tak, że administrator widzi co jest aktualnie uploadowane oraz ma możliwość przerwania tego. Do tego opcje umożliwiające ustawianie limitów uploadu na podstawie zakresów ip i innych rzeczy.

Niestety na razie nie mogę tego nikomu zaprezentować - projekt częściowo na zamówienie.
Go to the top of the page
+Quote Post
Diwi
post 5.11.2005, 21:15:42
Post #15





Grupa: Zarejestrowani
Postów: 245
Pomógł: 4
Dołączył: 22.01.2005

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


Hmm.. nie wiedziałem że w ankiecie odpowiedź może mieć 148.28%

Pozdrawiam
Go to the top of the page
+Quote Post
klops
post 7.11.2005, 22:00:04
Post #16





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 5.04.2005

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


dzieki, cos bede myslal smile.gif
Go to the top of the page
+Quote Post

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: 13.07.2025 - 06:27