TCP сервер и ошибка

Подключаем наши девайсы к компьютеру. Обсуждаются: порты, протоколы, драйвера, языки программирования и т.д.
Ответить
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

TCP сервер и ошибка

Сообщение Pooher »

Всем привет! Волей случая, в общеобразовательных целях решил заняться написанием WEB сервиса для своей игрушки. Общаться хочу по TCP.
Поставил дэнвер, написал простой сервер из примера php.net, и столкнулся с первой проблемой - никак не запустить его, постоянно выкидывает ошибку:
unable to bind address [0]: Обычно разрешается только одно использование адреса сокета (протокол/сетевой адрес/порт)
Дело встало, моих скудных познаний катастрофически не хватает для того, чтобы понять в чём дело.
Подскажите, пожалуйста, в какую сторону хоть копать-то)

Код: Выделить всё

#!/usr/local/bin/php -q
<?php
error_reporting(E_ALL);

/* Позволить сценарию зависнуть вокруг ожидания подключений */
set_time_limit(0);

/* Включить неявный вывод, так что мы видим то, что мы получаем
 * когда это приходит . */
ob_implicit_flush();

$address = '127.0.0.1';
$port = 86;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
    echo "socket_create() failed: reason: " . socket_strerror($sock) . "\n";
}

if (($ret = socket_bind($sock, $address, $port)) < 0) {
    echo "socket_bind() failed: reason: " . socket_strerror($ret) . "\n";
}

if (($ret = socket_listen($sock, 5)) < 0) {
    echo "socket_listen() failed: reason: " . socket_strerror($ret) . "\n";
}

do {
    if (($msgsock = socket_accept($sock)) < 0) {
        echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
        break;
    }
    /* Send instructions. */
    $msg = "\nWelcome to the PHP Test Server. \n" .
        "To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
    socket_write($msgsock, $msg, strlen($msg));

    do {
        if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
            echo "socket_read() failed: reason: " . socket_strerror($ret) . "\n";
            break 2;
        }
        if (!$buf = trim($buf)) {
            continue;
        }
        if ($buf == 'quit') {
            break;
        }
        if ($buf == 'shutdown') {
            socket_close($msgsock);
            break 2;
        }
        $talkback = "PHP: You said '$buf'.\n";
        socket_write($msgsock, $talkback, strlen($talkback));
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);

socket_close($sock);
?>


ЗЫ:Скрипт лежит в папке www. Запускаю в браузере localhost/script.php. Может не так надо? Просто я пока немного недопонимаю всей сути. Для меня это всё тёмный лес, в инете всё перерыл, инфы очень мало.
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Аватара пользователя
diafour
Встал на лапы
Сообщения: 109
Зарегистрирован: Пн янв 26, 2015 07:48:56
Откуда: Москва, Троицк

Re: TCP сервер и ошибка

Сообщение diafour »

Эта ошибка означает, что на порту 86 уже слушает другой процесс, скорее всего ранее запущенный. Есть такой флаг у сокета: SO_REUSEADDR, его нужно выставить, чтобы после того, как один процесс умер, не закрыв порт, второй мог переоткрыть порт. Вот по ссылке первый пример: http://php.net/manual/en/function.socket-set-option.php

А что за игрушка и почему не использовать готовый сервер, тот же апач из денвера, скрипт будет проще?

P.S. под web-сервисом обычно понимают общение по протоколу HTTP с SOAP сообщениями - для игрушек это точно overkill.
kalobyte
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Re: TCP сервер и ошибка

Сообщение kalobyte »

сегодня для таких задач используют фреймворки и пхп не заточен для написание подобных штук, лучше node.js или питон
но на пхп есть фреймворк для вебсокетов
http://www.phpbuilder.com/articles/appl ... ckets.html
вот фреймворк http://socketo.me/

вебсокеты работают в реальном времени и открывается только одно соединение на одного клиента
в ютубе есть 3 урока от "специалист" и там делают чат на вебсокете с сервером на .нет и чистом яваскрипте
тематические ответы только в форуме, в приват не пишите
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

Re: TCP сервер и ошибка

Сообщение Pooher »

Спасибо огромное за наводку! Буду копать SOAP.
ЗЫ: Давно не чувствовал себя нубом))
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Аватара пользователя
diafour
Встал на лапы
Сообщения: 109
Зарегистрирован: Пн янв 26, 2015 07:48:56
Откуда: Москва, Троицк

Re: TCP сервер и ошибка

Сообщение diafour »

Не-не-не, не надо soap, поберегите мозг :) Расскажите, что хотите от серверной части и что за игрушка? Тут вот про web-сокеты разговор зашёл - это для браузерной игры подойдёт. Про такую игру речь? Браузерная многопользовательская?
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

Re: TCP сервер и ошибка

Сообщение Pooher »

Не буду углубляться. Есть термостат, у него есть некоторое количество параметров. Мне надо отображать их на веб странице, и иметь возможность их поменять. Это задача-минимум. Доступ к сети обеспечивает sim900. Мне нужна концепция, и чтоб мозги по забору не развесить при освоении. PHP я выбрал, только по тому, что это первое, что попалось мне на глаза, и показалось не очень сложным. Ведь после многих лет асма на изучение си у меня ушло всего дня 2, но мк, скажу я вам, - это очень узко))

ЗЫ: SOAP - мозги закипают) Мне кажется для моей задачи всё должно быть гораздо проще (HTML форма<->сервер<-TCP->клиент)
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Аватара пользователя
diafour
Встал на лапы
Сообщения: 109
Зарегистрирован: Пн янв 26, 2015 07:48:56
Откуда: Москва, Троицк

Re: TCP сервер и ошибка

Сообщение diafour »

Sim 900 в термостате? Если мк у термостата какой-нибудь арм, можно попробовать сервер на нём же и поднять, сделать интерфейс как у домашних роутеров.

Если с sim900 работает пик или авр или вариант сервера на термостате не подходит, то можно поднять апач, сделать скрипт с формой для ввода и отображения параметров, а сами параметры скрипт будет сохранять в файл в формате, понятном термостату.

Например, апач на адресе 10.10.0.3 и в корне лежит файл с параметрами p.txt. тогда термостат открывает соединение с 10.10.0.3 и передаёт такую строку:
GET /p.txt HTTP/1.0\n\n

В ответ получает содержимое файла, например, параметры через запятую:
10,45,,67
Т.е. 4 параметра, 3ий не установлен.

В такой реализации не надо будет заморачиваться с сокетами - апач их уже умеет :) можно руками менять параметры и просить термостат их забрать - файл проще поправить, чем бд.
kalobyte
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Re: TCP сервер и ошибка

Сообщение kalobyte »

так ты бы сразу сказал, что тебе конкретно надо
для твоей задачи естественно сокеты на пхп это как по воробьям из пушки
твой сим должен открыть тцп сокет и соединиться по адресу на 80й порт
при этом послать в сокет такую строку

Код: Выделить всё

GET http://www.site.ru/temp.php?mode=get HTTP/1.0\r\n
Host: www.site.ru\r\n\r\n


далее пишеш тупо на пхп и сервер тебе не нужен, есть готовый апач, к которому пхп прикручен
твой пхп должен в ответ выдать температуру типа t=25
что-то типа echo $temp;
твой код в контроллере находит паттерн t= и понимает следущее число как температуру

только если в первом случае ты шлеш заголовок, то во втором случае ты получаеш данные
в хттп данные от заголовка разделяются двойным переносом строки и возвратом каретки
т.е. тебе сначала надо найти \r\n\r\n и потом уже парсить данные

как установить термостат?
посылаеш

Код: Выделить всё

GET http://www.site.ru/temp.php?mode=set&temp=30 HTTP/1.0\r\n
Host: www.site.ru\r\n\r\n


Host: http://www.site.ru надо передавать, чтобы апач понял, что обращаются к виртуальному хосту, коих на одном ип может быть целая куча

как распарсить запрос?
когда мы делаем GET http://www.s, то переменные будут храниться в глобальной переменной $_GET
например $mode = $_GET["mode"] в котором будет get или set
$temp = $_GET["temp"] и там будет число

естественно надо все это гавно проверить на правильность

для эмуляции работы твоего скрипта тебе надо плагин для браузера
http://restclient.net/

если ты хочеш делать все современно и круто, то есть готовые пхп фреймворки, которые за тебя делают 95% унылой работы, ты только должен написать логику работы твоего приложения
для твоей задачи нужен простой фреймворк
https://www.youtube.com/watch?v=0p6UDIiqWEg
почитай концепцию restful api, на хабре есть

что касается вебморды, то для современного стиля обычно используют яваскрипт фреймворк jquery
это обертка, которая упрощает написание всякого гимора
тебе нужно читать jquery ajax + валидатор на стороне клиента, чтобы клиент не ввел левое
это типа правила хорошего тона, но на сервере тоже нужна валидация, там фреймворк вроде делает базовую валидацию входящих данных

в ютубе есть видосы по жквери, за час-два разберешся
еще есть готовые модули визуальные для рисования вебинтерфейса
эта библиотека бесплатна, если твой проект некоммерческий
http://www.jqwidgets.com/jquery-widgets ... /index.htm
http://www.jqwidgets.com/jquery-widgets ... nality.htm
тематические ответы только в форуме, в приват не пишите
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

Re: TCP сервер и ошибка

Сообщение Pooher »

Спасибо всем огромное! Буду пробовать разбираться. Очень надеюсь на вашу дальнейшую помощь.
Как говорится - первый раз всегда больно))
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Аватара пользователя
Мурик
Друг Кота
Сообщения: 3383
Зарегистрирован: Пн окт 11, 2010 19:00:08

Re: TCP сервер и ошибка

Сообщение Мурик »

Если сервер на своем компе, то можно написать его на чем угодно. Пример градусника с доступом через интернет.
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

Re: TCP сервер и ошибка

Сообщение Pooher »

На данный момент я вижу выполнение моей задачи так:

sim900 делает запрос типа www.site.ru/postParameters.php?temp1=xx
скрипт обрабатывает переменную temp1 и пишет её значение в БД.

для доступа к изменению параметров термостата, со стороны sim900 я запускаю сервер, передаю его ip и порт www.site.ru/postParameters.php?ip=xxx.x ... xx?port=xx

для онлайн отображения информации от термостата надо использовать ajax. Скрипт периодически считывает параметры из БД и выводит на страницу.

Поправьте, пожалуйста, если не так, или подскажите, может проще можно?
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Аватара пользователя
Мурик
Друг Кота
Сообщения: 3383
Зарегистрирован: Пн окт 11, 2010 19:00:08

Re: TCP сервер и ошибка

Сообщение Мурик »

А разве можно вот так взять и задать произвольный IP серверу?
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

Re: TCP сервер и ошибка

Сообщение Pooher »

IP выдаст сотовый оператор.
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: TCP сервер и ошибка

Сообщение Tolmi »

Pooher писал(а): может проще можно?

Мне кажется, что городить отдельный сервер занятие в данном случае бессмысленное. Если sim900 на регулярной основе делает запросы web-серверу, то изменение параметров можно просто передавать внутри ответов на эти запросы. т.е. в ответ на запрос www.site.ru/postParameters.php?temp1=xx на веб сервере во-первых записывается температура в бд, а во-вторых проверяется не нужно ли передать sim900 команды на изменение параметров. А потом в ответе сервера кроме 200 OK обычным текстом передавать PARAM_XXX=Value,PARAM_YYY=Value и т.д. Разбор такого ответа будет тривиальным занятием даже на примитивных железках. И не нужно городить отдельный сервер.
Единственный параметр, который не сменить таким образом - это адрес самого www.site.ru, вернее, и это можно, если работают одновременно и старый, и новый сервер.
In theory, theory and practice are the same. In practice, they're not.
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

Re: TCP сервер и ошибка

Сообщение Pooher »

Смысл поднятия сервера на SIM900 в том, чтобы параметры изменялись "моментально", и сразу после отправки пользователь мог получить ответ, приняты ли данные, всё ли в порядке с железкой. Без сервера на SIM я решения не увидел.
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
kalobyte
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Re: TCP сервер и ошибка

Сообщение kalobyte »

Pooher писал(а):Без сервера на SIM я решения не увидел.

вебсокеты http://en.wikipedia.org/wiki/WebSocket
твой сим будет клиентом, который открывает тцп сокет и шлет определенную пургу а ля хттп
только тебе тогда лучше взять питон, я вчера на гитхабе смотре серверы вебсокетов на питоне
заодно вебморду сделаеш так же, будет все в реальном времени

http://metroui.org.ua/ вот даже годный цсс фреймворк нашел, мне метро нравится
или http://webix.com/
тематические ответы только в форуме, в приват не пишите
Аватара пользователя
diafour
Встал на лапы
Сообщения: 109
Зарегистрирован: Пн янв 26, 2015 07:48:56
Откуда: Москва, Троицк

Re: TCP сервер и ошибка

Сообщение diafour »

Pooher писал(а):На данный момент я вижу выполнение моей задачи так:

sim900 делает запрос типа http://www.site.ru/postParameters.php?temp1=xx
скрипт обрабатывает переменную temp1 и пишет её значение в БД.

для доступа к изменению параметров термостата, со стороны sim900 я запускаю сервер, передаю его ip и порт http://www.site.ru/postParameters.php?i ... xx?port=xx

для онлайн отображения информации от термостата надо использовать ajax. Скрипт периодически считывает параметры из БД и выводит на страницу.

Поправьте, пожалуйста, если не так, или подскажите, может проще можно?


Схема вполне нормальная, количество компонентов упростить можно только перенеся http сервер непосредственно в термостат, но это похоже не вариант?

Код: Выделить всё

Desktop/Mobile            site.ru               gprs-dynamic-ip
+----------+           +----------+          +----------+
|          |           |             |          |            |
| Браузер  |   80      | HTTP сервер |   8000   | Термостат  |
|          |<--------->| php         |<-------->|            |
| JS       |           |             |          | SIM900     |
|          |           | DB          |          |            |
+----------+           +----------+          +----------+
В этой схеме можно немного упростить взаимодействие, если учесть тот факт, что http сервер всегда знает ip адрес с которого пришёл запрос (реверсивные прокси и нат пока оставим за рамками). Поэтому, зафиксировав порт термостата, скажем 8000, достаточно будет периодически отправлять запрос с показаниями (http://www.site.ru/postParameters.php?temp1=xx), сервер же при разборе запроса будет сохранять в БД сразу и temp1 из query строки и ip адрес из свойств запроса.

В случае вебсокетов взаимодействие совсем упрощается, серверу не надо знать ip и порт для обратного коннекта. Между термостатом и http-сервером по сути открывается канал для передачи от термостата показаний, а от сервера - команд на изменение параметров. Если соединение рвётся, то термостат просто переподключается. Браузер тоже может открывать веб-сокет к тому же скрипту и обновлять показания по команде от сервера вместо периодического ajax опроса. В скрипте на сервере нужно будет получать показания из сокета термостата и отправлять их в сокеты браузеров и наоборот: получать команды на изменение параметров от браузеров и отправлять их в термостат. В промежутке можно сохранять данные в БД. Т.е. у скрипта будет два набора сокетов, между которыми он перекидывает сообщения. Надо будет только разделить сокеты на «термостатные» и «браузерные», но это тоже не слишком сложно, достаточно при коннекте передавать какой-нибудь простенький идентификатор типа "termo" и "browser". Данная схема масштабируется как по клиентам, так и по термостатам =) Ещё про вебсокеты можно сказать, что в случае их использования не будет тратиться время на установление tcp-соединений, т.е. от нажатия на кнопку в браузере до смены параметра в устройстве будет проходить минимально возможное время.

В дополнение к ссылкам на питон — исходники для ардуины: https://github.com/adik/webgsmcontrol


Не ясны возможности термостата. Какой там МК? А то может там линукс и всё на баш-скриптах можно сделать %)

P.S. kalobyte спасибо за webix, попробую где-нибудь, на вид шустрее, чем extjs.
Ответить

Вернуться в «Интеграция с ПК»