Другие языки программирования и технологии
PHP и UDP-сервер: Проблема с приёмом информации
Есть udp-демон, написаный на PHP, который собирает информацию с игрового сервера. Логи до него доходят, но не полностью, если поток сильно плотный, то может пропустить 1 строку. Вот собственно код: $address="192.168.1.2"; $port=27500; while(true){ $socket=socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1); socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1); socket_bind($socket,$address,$port); $buf=socket_read($socket,100,PHP_BINARY_READ); file_put_contents("logs/cstrike.log","$buf\n",FILE_APPEND); } Вместо socket_read() использовались и socket_recv() и socket_recvfrom(), но никакой разницы нет. Каким образом можно заставить скрипт принимать все входящие сообщения?
Выше совершенно верно написали, что UDP - протокол без гарантии доставки. Если вам нужна гарантированная доставка по UDP - то это можно реализовать только внеся изменения и в сервер, и в клиент (и это, фактически, будет надстройка над UDP)
Далее:
1. Использование недоязыка PHP для создания демонов, работающих под нагрузкой - это очень плохая идея. Это же относится в большей или меньшей степени и к другим интерпретируемым языкам. Демоны для обработки данных с высокой нагрузкой надо писать на С/С++. Также неплохо бы встроить в них какую-либо обработку ошибок и нештатных ситуаций.
2. Идея построчной записи в лог в ответ на каждый пук сервера, реализованная в строчке file_put_contents("logs/cstrike.log","$buf\n",FILE_APPEND); мало подходит для применения под нагрузкой. Надо стараться минимизировать количество операций ввода-вывода
3. Идея вешать на UDP сокет, принимающий юникаст с одного заранее известного адреса SO_BROADCAST и SO_KEEPALIVE лично мне представляется очень странной :D Если уж так хочется поиграться с опциями - посмотрите в сторону SO_RCVBUF
Далее:
1. Использование недоязыка PHP для создания демонов, работающих под нагрузкой - это очень плохая идея. Это же относится в большей или меньшей степени и к другим интерпретируемым языкам. Демоны для обработки данных с высокой нагрузкой надо писать на С/С++. Также неплохо бы встроить в них какую-либо обработку ошибок и нештатных ситуаций.
2. Идея построчной записи в лог в ответ на каждый пук сервера, реализованная в строчке file_put_contents("logs/cstrike.log","$buf\n",FILE_APPEND); мало подходит для применения под нагрузкой. Надо стараться минимизировать количество операций ввода-вывода
3. Идея вешать на UDP сокет, принимающий юникаст с одного заранее известного адреса SO_BROADCAST и SO_KEEPALIVE лично мне представляется очень странной :D Если уж так хочется поиграться с опциями - посмотрите в сторону SO_RCVBUF
Никаким.
UDP - протокол БЕЗ гарантии доставки дейтаграмм.
UDP - протокол БЕЗ гарантии доставки дейтаграмм.
Бауыржан Жауенов
Самое интересное, что на perl подобное извращение работает без проблем))
главная ошибка, в том, что вы используете препроцессор гипертекста в таком неподходящем для него деле.
оставьте скрипт на перле в покое, пусть себе работает.
но если неймется - увеличьте размер буфера чтения. 100 байт видимо маловато
$address="192.168.1.2";
$port=27500;
$socket=socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1);
socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
socket_bind($socket,$address,$port);
while(true) {
$len = socket_recvfrom($socket, $buf, 10000, 0, $peeraddr, $peerport);
print "DEBUG: recieved $len bytes from $peeraddr:$peerport\n";
file_put_contents("cstrike.log","$buf\n",FILE_APPEND);
}
оставьте скрипт на перле в покое, пусть себе работает.
но если неймется - увеличьте размер буфера чтения. 100 байт видимо маловато
$address="192.168.1.2";
$port=27500;
$socket=socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1);
socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
socket_bind($socket,$address,$port);
while(true) {
$len = socket_recvfrom($socket, $buf, 10000, 0, $peeraddr, $peerport);
print "DEBUG: recieved $len bytes from $peeraddr:$peerport\n";
file_put_contents("cstrike.log","$buf\n",FILE_APPEND);
}
Бауыржан Жауенов
Скрипт я уже поправил, работает на ура))
Похожие вопросы
- MySQL и PHP SELECT * FROM `users` Как вывести определенную информацию из графы БД, человека который сейчас авторизован
- Изучил HTML,с ним всё ясно:каждый тег делает своё дело.А с CSS,PHP и Java Script проблемы.
- [Delphi] консольное приложение, UDP
- Помогоите с UDP сокетами! (с++)
- Помогите пожалуйста, проблема с php и html
- если есть тут знатоки,то пожалуйста раскажите какой язык написания WEB сайтов лучше php и сервер mysql или HTML?
- Как архивировать сайт большого размера средствами Php? На сервере есть лимиты памяти.
- Почему клиент с другого компьютера не подключается к серверу через интернет? Клиент и сервер написаны на C#.
- С какого языка начинать изучения программирования Pascal/PHP/Python?
- Могут ли спецслужбы сделать человека неанонимным, если он пользуется прокси сервером при таких условиях ?
$buf=socket_read($socket,100,PHP_BINARY_READ);
file_put_contents("logs/cstrike.log","$buf\n",FILE_APPEND);
нужно было взять в отдельный whlie(true)