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:
$Dlugosc_Ramki_Lan = '552' ;
$address = '192.168.2.111';
$port = 80;
$str = "CMAT";
for ($i = 0
, $j = strlen($str); $i < $j; $i++) { $dec_array[] = ord($str{$i});
}
$tab[0] = $dec_array[0];
$tab[1] = $dec_array[1];
$tab[2] = $dec_array[2];
$tab[3] = $dec_array[3];
/* zliczam ile zer mam wpisać pomiedzy pierwsze 4 bity a ostatnie 3 */
$ile_elemntow = 0;
foreach($tab as $v)
{
$ile_elemntow++;
}
$sumy = __suma(549, $tab);
/* wyluwam sobie jak wygląda HEXem komenda 'CMAT' */
for($n=0;$n < $ile_elemntow;$n++)
{
}
/* 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*/
/* do zmiennej ping dodaje komende CMAT hexalnie, tak jak poniżej */
$ping = "\x43\x4D\x41\x54";
/* dodaje wartości 0 hex na pozostałe bity ramki, czyli od 4 włącznie do 549 */
for($i=$ile_elemntow; $i<$Dlugosc_Ramki_Lan-3; $i++) {
$ping .= "\x0";
}
/* wpisuje 3 ostantie bity ramki które sobie wyrzuciłem na ekran wcześniej */
$ping .= "\xD6\x3\x0D";
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connect = socket_connect($socket, $address, 80);
$write = socket_write($socket, $ping, $Dlugosc_Ramki_Lan);
$dane = socket_read($socket, $Dlugosc_Ramki_Lan);
socket_close($socket);
Echo '<h2 class="sec">Odczyt daty i godziny</h2>'; for ($i = 0
, $j = strlen($dane); $i < $j; $i++) { $dec_array2[] = ord($dane{$i}).' ';
}
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:
$Dlugosc_Ramki_Lan = '552' ;
$address = '192.168.2.111';
$port = 80;
$str = "CMAT";
for ($i = 0
, $j = strlen($str); $i < $j; $i++) { $dec_array[] = ord($str{$i});
}
$tab[0] = $dec_array[0];
$tab[1] = $dec_array[1];
$tab[2] = $dec_array[2];
$tab[3] = $dec_array[3];
$ile_elemntow = 0;
foreach($tab as $v)
{
$ile_elemntow++;
}
$sumy = __suma(549, $tab);
for($n=0;$n < $ile_elemntow;$n++)
{
}
/* znalazłem funkcję sprintf z parametrem HEX, i właśnie podjąłem próbę w poniższy sposób */
$msg_data_ping = sprintf("\x%X",$dec_array[0
]); $msg_data_ping .= sprintf("\x%X",$dec_array[1
]); $msg_data_ping .= sprintf("\x%X",$dec_array[2
]); $msg_data_ping .= sprintf("\x%X",$dec_array[3
]);
for($i=$ile_elemntow; $i<$Dlugosc_Ramki_Lan-3; $i++) {
$msg_data_ping .= sprintf("\x%X", "00"); }
$msg_data_ping .= sprintf("\x%X",$sumy[0
]); $msg_data_ping .= sprintf("\x%X",$sumy[1
]); $msg_data_ping .= sprintf("\x%X","13");
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connect = socket_connect($socket, $address, 80);
$write = socket_write($socket, $msg_data_ping, $Dlugosc_Ramki_Lan);
$dane = socket_read($socket, $Dlugosc_Ramki_Lan);
socket_close($socket);
echo '<h2 class="sec">Odczyt daty i godziny</h2>'; for ($i = 0
, $j = strlen($dane); $i < $j; $i++) { $dec_array2[] = ord($dane{$i}).' ';
}
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.