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"; $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); $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"; $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 */ for($i=$ile_elemntow; $i<$Dlugosc_Ramki_Lan-3; $i++) { } $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); $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.