Есть прога на смартфон - GPS-трекер, отправляет данные по UDP на прописанный сервер и порт. Отправляет простым текстом, строка с данными, разделенными пробелами. Получать проблем нет, нашел, разобрался (раньше не имел дела с UDP вообще, так-то уже лет 15 вожусь потихоньку). Проблема - программа требует посылки ответа, иначе начинает капризничать, копить точки в кэше, высылать и повторно и т.д. http://doro.poltava.ua/gpsm/gpsmta.html#p17 Читаю про UDP и не понимаю, как это. Там вроде нужно знать IP-адрес трекера и т.п... Получаю честно найденным в енторнетах кодом: http://pastebin.com/d46jYZPN Как отправить ответ?
UDP очень похож на TCP. На php в работе с ними вообще разницы нет. Где-то в районе 53-й строчки используй функцию http://php.net/socket_write для передачи данных в сокет после прочтения (если данные были получены).
Читал. Попытался применить. Что-то не понимаю, видимо. Последняя попытка была socket_send($socket,$message,count($message),MSG_DONTROUTE); Warning: socket_send(): unable to write to socket [89]: Destination address required in ... socket_write($socket,$message) там, где вы сказали: Warning: socket_write(): unable to write to socket [89]: Destination address required in ... Откуда его брать? ЗЫ: по TCP тоже ессно ничего не передавал. В смысле, с сокетами вообще не работал. Может какой-то фак для чайников по сокетам нужно читать?
Код (Text): if (False === ($r = socket_read($socket, 1024))) { $errorcode = socket_last_error(); $errormsg = socket_strerror($errorcode); if ($errorcode!='11') { echo "error reading : [$errorcode] $errormsg <br>\n"; } } else { socket_write($socket, 'all right!'); } как-то так
Ну так и сделано. Только было "если не пуст результат", вот если угодно через else: Код (PHP): while(1){ usleep(0.5 * 1000000); // 0.5 seconds if (False === ($r = socket_read($socket, 1024))) { $errorcode = socket_last_error(); $errormsg = socket_strerror($errorcode); if ($errorcode!='11') { echo "error reading : [$errorcode] $errormsg <br>\n"; } } else { $a=explode(" ",$r); socket_write($socket,$a[0]); echo $r; } if ($r!='') { echo "<pre>".date("d.m.Y H:i:s",$a[1])." - ".$r."</pre>\n"; } flush_buffers(); } Выхлоп: Код (PHP): Socket created Socket bind OK Warning: socket_write(): unable to write to socket [89]: Destination address required in /blablabla/gpstracking/tracking_web.php on line 69 352019030137388 1444843381 55.0000 38.0000 20 355 14 151 00 63 29 0 0 14.10.2015 20:23:01 - 352019030137388 1444843381 55.0000 38.0000 20 355 14 151 00 63 29 0 0 Warning: socket_write(): unable to write to socket [89]: Destination address required in /blablabla/gpstracking/tracking_web.php on line 69 352019030137388 1444843136 55.54735 38.900351 1 79 18 146 00 64 28 0 0 14.10.2015 20:18:56 - 352019030137388 1444843136 55.0000 38.0000 1 79 18 146 00 64 28 0 0 ЗЫ: магическое "олл райт" тоже не помогает ;-) PHP, JavaScript, SQL и другой код пишите внутри тегов Код ( (Unknown Language)): [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
Попробуй после 39-й добавить Код (Text): socket_listen($socket); socket_accept($socket); и убери установку сокета в неблокирующим режим.
Попробовал. socket_listen(): unable to listen on socket [95]: Operation not supported socket_accept(): unable to accept incoming connection socket_write(): unable to write to socket [89]: Destination address required пичаль
Точняк. Эти функции для TCP, в котором существует установка соединения. В контексте соединения хранится информация о IP-адресе противоположной стороны. Функция socket_read() из той же оперы. socket_recvfrom() умеет сохранять в переменную ip-адрес клиента. вместо Код (Text): if (False === ($r = socket_read($socket, 1024))) { попробуй Код (Text): if (False === ($ok = socket_recvfrom($socket, $r, 1024, 0, $remote_ip, $remote_port))) { переменные $r, $remote_ip и $remote_port создавать не обязательно, поскольку они принимаются по ссылке и используются для сохранения информации. Потом соответственно вместо Код (Text): socket_write делай Код (Text): $response = 'All right!'; socket_sendto($socket, $response, strlen($response), 0, $remote_ip, $remote_port);
Уже лучше. Правда, после повторного запуска скрипта Warning: socket_recvfrom(): unable to recvfrom [11]: Resource temporarily unavailable И ничего с этим поделать не могу... Странно, вроде скрипт прибивается, переменные очищаются... Порт слушается... $ sudo lsof -i :9999 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME /usr/sbin 13670 www-data 22u IPv4 183259206 0t0 UDP *:9999
А в старой версии скрипта все нормально прибивалось убийством процесса. Как я могу использовать socket_close(), когда скрипт работает в бесконечном цикле и выйти из него можно только перезагрузив страницу, а тогда ни о каком resource $socket не может быть и речи - он давно потерян?
Убивай процесс сигналом SIGTERM, а в скрипте назначь функцию для обработки pcntl сигнала SIGTERM, которая закроет сокет и завершит скрипт с помощью exit().