Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Socket write - wysyłanie zmiennych w ramce
Forum PHP.pl > Forum > PHP
gigininksu
Witam,

Prosiłbym o pomoc w kwestii wysyłania pakietów, ramek za pomocą php i funkcji socket_write. Posiadam urządzenia podpięte pod TCP/IP, aby się z nim skomunikować muszę przesłać mu odpowiednią paczkę aby urządzenie mi odpowiedziało.

Mianowicie pierwsze 4 bity to komenda, następne bity to zera(długość ramki 552(zawsze!)), na 3 ostatnich bitach od końca jest kolejno suma kontrolna 1 i suma kontrolna 2 i zamknięcie ramki zawsze 13 (DEC) ostatni bit.

Gdy wpisuję mu wartości w HEX "z palca", tak jak przykład poniżej, wszystko działa poprawnie, urządzenie odpowiada i jest wszystko OK. Jednak gdy w grę wchodzą zmienne jest już problem.

DZIAŁAJĄCY PRZYKŁAD:

  1. $Dlugosc_Ramki_Lan = '552' ;
  2. $address = '192.168.2.111';
  3. $port = 80;
  4.  
  5. $str = "CMAT";
  6.  
  7. for ($i = 0, $j = strlen($str); $i < $j; $i++) {
  8. $dec_array[] = ord($str{$i});
  9. }
  10.  
  11. $tab[0] = $dec_array[0];
  12. $tab[1] = $dec_array[1];
  13. $tab[2] = $dec_array[2];
  14. $tab[3] = $dec_array[3];
  15. /* zliczam ile zer mam wpisać pomiedzy pierwsze 4 bity a ostatnie 3 */
  16. $ile_elemntow = 0;
  17. foreach($tab as $v)
  18. {
  19. $ile_elemntow++;
  20. }
  21.  
  22. $sumy = __suma(549, $tab);
  23. /* wyluwam sobie jak wygląda HEXem komenda 'CMAT' */
  24. for($n=0;$n < $ile_elemntow;$n++)
  25. {
  26. '\x'.strtoupper(dechex($dec_array[$n]));
  27. }
  28.  
  29. echo "Suma kontrolna 0: ".$suma_kontrolna0 = "\x".strtoupper(dechex($sumy[0]));
  30.  
  31. echo "Suma kontrolna 1: ".$suma_kontrolna1 = "\x".strtoupper(dechex($sumy[1]));
  32.  
  33. /* wypluwam sobie w widoku jak wyglada wartosc w HEX dopisując \x --- \x0D to HEX z 13 DEC ---- całość to 3 ostatnie bity ramki*/
  34. echo $suma_kontrolna0.$suma_kontrolna1.'\x0D<br />'; /* "\haha.gif6\x3\x0D" */
  35.  
  36. /* do zmiennej ping dodaje komende CMAT hexalnie, tak jak poniżej */
  37. $ping = "\x43\x4D\x41\x54";
  38.  
  39. /* dodaje wartości 0 hex na pozostałe bity ramki, czyli od 4 włącznie do 549 */
  40. for($i=$ile_elemntow; $i<$Dlugosc_Ramki_Lan-3; $i++) {
  41. $ping .= "\x0";
  42. }
  43. /* wpisuje 3 ostantie bity ramki które sobie wyrzuciłem na ekran wcześniej */
  44. $ping .= "\xD6\x3\x0D";
  45. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  46. $connect = socket_connect($socket, $address, 80);
  47.  
  48. $write = socket_write($socket, $ping, $Dlugosc_Ramki_Lan);
  49. $dane = socket_read($socket, $Dlugosc_Ramki_Lan);
  50. socket_close($socket);
  51.  
  52. Echo '<h2 class="sec">Odczyt daty i godziny</h2>';
  53. for ($i = 0, $j = strlen($dane); $i < $j; $i++) {
  54. $dec_array2[] = ord($dane{$i}).' ';
  55. }


Pięknie urządzenie odpowiada danymi, wszystko działa.

Problem gdy zamiast wartości np. kończącej całą ramkę czyli: $ping .= "\xD6\x3\x0D"; zastąpię zmiennymi, czyli: $ping .= $suma_kontrolna0.$suma_kontrolna1.'\x0D ; już urządzenie nie rozumie i wywala się na plecy, a obie te zmienne wyglądają idenczycznie w postaci: "\xD6\x3\x0D".

OK, może on odbiera to jako string pomyślałem. Kolejna próba:

  1. $Dlugosc_Ramki_Lan = '552' ;
  2. $address = '192.168.2.111';
  3. $port = 80;
  4.  
  5. $str = "CMAT";
  6.  
  7. for ($i = 0, $j = strlen($str); $i < $j; $i++) {
  8. $dec_array[] = ord($str{$i});
  9. }
  10.  
  11. $tab[0] = $dec_array[0];
  12. $tab[1] = $dec_array[1];
  13. $tab[2] = $dec_array[2];
  14. $tab[3] = $dec_array[3];
  15. $ile_elemntow = 0;
  16. foreach($tab as $v)
  17. {
  18. $ile_elemntow++;
  19. }
  20.  
  21. $sumy = __suma(549, $tab);
  22.  
  23. for($n=0;$n < $ile_elemntow;$n++)
  24. {
  25. '\x'.strtoupper(dechex($dec_array[$n]));
  26. }
  27.  
  28. /* znalazłem funkcję sprintf z parametrem HEX, i właśnie podjąłem próbę w poniższy sposób */
  29. $msg_data_ping = sprintf("\x%X",$dec_array[0]);
  30. $msg_data_ping .= sprintf("\x%X",$dec_array[1]);
  31. $msg_data_ping .= sprintf("\x%X",$dec_array[2]);
  32. $msg_data_ping .= sprintf("\x%X",$dec_array[3]);
  33.  
  34. for($i=$ile_elemntow; $i<$Dlugosc_Ramki_Lan-3; $i++) {
  35. $msg_data_ping .= sprintf("\x%X", "00");
  36. }
  37. $msg_data_ping .= sprintf("\x%X",$sumy[0]);
  38. $msg_data_ping .= sprintf("\x%X",$sumy[1]);
  39. $msg_data_ping .= sprintf("\x%X","13");
  40.  
  41. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  42. $connect = socket_connect($socket, $address, 80);
  43.  
  44. $write = socket_write($socket, $msg_data_ping, $Dlugosc_Ramki_Lan);
  45. $dane = socket_read($socket, $Dlugosc_Ramki_Lan);
  46. socket_close($socket);
  47. echo '<h2 class="sec">Odczyt daty i godziny</h2>';
  48. for ($i = 0, $j = strlen($dane); $i < $j; $i++) {
  49. $dec_array2[] = ord($dane{$i}).' ';
  50. }


Powyższa próba również zakończyła się niepowodzeniem, czy wygładało to tak: sprintf("\x%X", "00");, czy tak sprintf("%X", "00");, czy tak sprintf("\\x%X", "00"); za każdym razem błąd komunikacji.

Prosiłbym o jakiekolwiek sugestie, pewnie ktoś walczył z tym problemem.

Problemem jest przesyłanie socket_write ramki w postaci HEX.
mls
Do przesyłania danych binarnych zdecydowanie wygodniej użyć pack. To, co jest w kodach powyżej to jakaś rzeźba i nawet nie wiadomo o co tam chodzi...
gigininksu
Cytat(mls @ 23.01.2012, 11:51:51 ) *
Do przesyłania danych binarnych zdecydowanie wygodniej użyć pack. To, co jest w kodach powyżej to jakaś rzeźba i nawet nie wiadomo o co tam chodzi...


No spoko, funkcja pack, czyli w jaki sposób ma wyglądać paczka?
  1.  
  2. $Dlugosc_Ramki_Lan = '552' ;
  3. $address = '192.168.2.111';
  4. $port = 80;
  5.  
  6. $str = "CMAT";
  7.  
  8. for ($i = 0, $j = strlen($str); $i < $j; $i++) {
  9. $dec_array[] = ord($str{$i});
  10. }
  11.  
  12. $tab[0] = $dec_array[0];
  13. $tab[1] = $dec_array[1];
  14. $tab[2] = $dec_array[2];
  15. $tab[3] = $dec_array[3];
  16. $ile_elemntow = 0;
  17. foreach($tab as $v)
  18. {
  19. $ile_elemntow++;
  20. }
  21.  
  22. $sumy = __suma(549, $tab);
  23.  
  24. for($n=0;$n < $ile_elemntow;$n++)
  25. {
  26. strtoupper(decbin($dec_array[$n]));
  27. }
  28.  
  29. $q = strtoupper(decbin($dec_array[0]));
  30. $w = strtoupper(decbin($dec_array[1]));
  31. $e = strtoupper(decbin($dec_array[2]));
  32. $r = strtoupper(decbin($dec_array[3]));
  33.  
  34. echo $suma_kontrolna0 = strtoupper(decbin($sumy[0]));
  35.  
  36. echo $suma_kontrolna1 = strtoupper(decbin($sumy[1]));
  37.  
  38.  
  39.  
  40. $koniec = decbin(13);
  41.  
  42. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  43. $connect = socket_connect($socket, $address, 80);
  44.  
  45.  
  46.  
  47. $pak = pack("nvc*", $q, $w, $e, $r, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, $suma_kontrolna0,$suma_kontrolna1,$koniec);
  48.  
  49. $write = socket_write($socket, $pak, $Dlugosc_Ramki_Lan);
  50. $dane = socket_read($socket, $Dlugosc_Ramki_Lan);
  51. socket_close($socket);
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.