Golikov A.
Dec 22 2013, 13:53
надо знать про сокеты вот что.
1. сокет - это тройка параметров IP адрес, Порт, Протокол (TCP/UDP), ни при каких условиях не может быть 2 сокетов с одинаковой тройкой параметров, хоть 1 параметр да должен отличаться...
2. сокет может быть со стороны сервера, а может быть со стороны клиента. Клиент подключается к серверу, сервер ждет соединения клиента.
Как раз включение сервера на ожидание соединение и есть прослушка, listen mode. То есть он получает все обращения к этому сокету, и ищет среди них запрос на соединение (для ТСР), на который отвечает, устанавливает связь, и сокет переходит в conected mode.
если вы закроете законекченый сокет, он разорвет соединение и вернется в режим прослушки. Если вы закроете сокет на прослушке, он удалиться совсем.
тот номер что вы получаете при создании сокета - это всего лишь номер для отличия одного вашего сокета внутри вашей системы от другого. Внутри стэка стоит соответствие между этим номером и той тройкой параметров что были в начале. Потому если вы сделали сокеты
1 2 3 4 5, а потом 2 закрыли то он просто пропадет. При следующем создании сокета может так оказаться что он опять получит номер 2, а может номе 6, этого никто не знает, да это и не надо, главное запомнить какой номер дали при создании и все.
3. Сокет в conected mode это уже не 3, а 5 параметров
IP местный и клиента, Порт местный и клиента, Протокол. То есть вы можете создать сокет с портом 5, поставить его на прослушку, и когда к вам присоединится клиент с портом 7, вы можете спокойно создать новый сокет с портом 5, который сможет принять новое соединение, но либо по другому порту либо с другого IP.
для netcat - если по умолчанию она конектится на порт 7.
netcat 192.168.0.1 80
причем обратите внимание ваша сетевая карта и устройство должны быть в одной подсети
потом просто пишите текст в командную строку, и данные пошли.
SocketNumber равен 4. При этом в tcp_callback не ходит, хотя прием идет и АСК отвечает тоже. При передаче более 4 байт имею следующую картину:
Нажмите для просмотра прикрепленного файлаПоставил порт 3000 и в tcp_callback стало заходить.
Теперь интересует такая штука. Вот я получил указатель и число байт. Я так понимаю, что из tcp_callback нужно выйти как можно быстрее? т.е. живенько все скопировать в свой буфер и выйти из tcp_callback?
А как услать свой пакет в ответ?
Golikov A.
Dec 22 2013, 17:56
ну скорость выхода из функций должна соответствовать режиму работы программы... Все данные что вы получили в этой функции для ТСР считаются принятыми, и если вы их никуда не положите и не обработаете, то они просто потеряются. Дальше ТСР за ними уже не следит.
Если у вас задействована функция окна, то надо не забывать его очищать tcp_reset_window(Soc). Иначе данные застопорятся.
чтобы послать данные надо их как бы послать

sendbuf = tcp_get_buf(data) - создаем буфер отправляемых данных, буфер с которым работает ТСР
tcp_send - отправляем данные
перед отправкой имеет смысл проверить
tcp_get_state - чтобы был в конекте
tcp_check_send - что может оправлять
tcp_max_dsize - сколько макс данных можно заслать, мало ли вдруг на другом конце окно забилось.
Цитата
sendbuf = tcp_get_buf(data) - создаем буфер отправляемых данных, буфер с которым работает ТСР
Т.е. по сути происходит выделение буфера указанного размера для отправки?
Вообще говоря меня настораживает этот способ т.к. наверняка ведется работа с указателями. Как бы чего не вышло. Есть ли какие-то рекомендации по опыту работы чтоб гарантировано не случился сбой? Вот например, мне нужно передать массив 2 кБ, как в этой ситуации поступить? Объявить буфер 2 кБ и более? Получается нужно вручную следить за выделением памяти и страховаться на все случаи жизни или как это будет? Максимальный оазмер, как я понял 1460 байт. Т.е. отправлять длинную посылку нужно с разбивкой самостоятельно?
Golikov A.
Dec 23 2013, 12:10
tcp_get_buf
не спроста так называется, не спроста с тср начинается%)..
это штука буфер для отправки, но не просто буфер, это буфер в очереди ТСР сообщений, за которым следит ТСР.
естественно если у вас кончиться память то будет ошибка, там даже есть обработчик критических ошибок с while (1) в конце, чтоб у новичков проекты висли, наверное%)...
После того как данные помещены на отправку, их обработают, поделят на пакеты и отправят, после чего самостоятельно уничтожат этот буфер. Это к вопросу почему нельзя передать указатель на свой буфер.
Про максимальный размер вы не правильно поняли

есть так называемый жумбофрейм он до 8К может быть, не знаю правда поддерживает его кеил или нет. Более того я рекомендовал еще глядеть на функции tcp_max_dsize, совершенно спокойно при забитом окне может так оказаться что и 1460 не сможет послать, и даже 54.
Всеравно пока не ясно как отослать много байт. Вот есть у кейла такой пример:
Код
#include <rtl.h>
#include <string.h>
BOOL send_datalog () {
U8 *sendbuf;
U16 maxlen;
if (tcp_check_send (tcp_soc)) {
/* The socket is ready to send the data. */
maxlen = tcp_max_dsize (tcp_soc);
sendbuf = tcp_get_buf (maxlen);
memcpy (sendbuf, data_buf, maxlen);
tcp_send (tcp_soc, sendbuf, maxlen);
return (__TRUE);
}
return (__FALSE);
}
Исходя из
Код
memcpy (sendbuf, data_buf, maxlen);
я не могу услать больше чем maxlen. Что-то совсем не пойму как разбивка будет происходить. Ну вот ушла часть размером maxlen и еще три таких осталось. Помогите понять идею. Спасибо.
Golikov A.
Dec 23 2013, 13:21
вот так и будет
у меня буфер в который я кладу данные на отправку.
время от времени вызывается функция отправки. Если можно отправить весь буфер отправляю весь, если нет, то отправляю сколько можно, остальное остается в буфере до следующего раза. Отправка происходит как в примере, создается буфер с оптравляемыми данными (или частью если все отправить нельзя) и передается в сэнд. Если в этот раз сокет вообще не может отправлять, то весь буфер остается до след раза.
Вы про окно ТСР знаете? Во время работы то комму отправляете данные информирует вас о том количестве байт что он готов принять, и вы по какой угодно технологии, с буфером или без, с указателями или ДМА, вы не имеете права посылать больше чем он может принять. Так что следить за допустимым для отправки числом байт вы обязаны.
Да, вот кстати уже давно хотел спросить про окна, ранее упоминавшиеся. Что это и как и для чего...
Golikov A.
Dec 23 2013, 14:40
да в целом все просто, это способ контроля потока.
Окно - это размер памяти для приема новых данных, каждые поступающие данные уменьшают этот размер, каждые обработанные данные освобождают окно. При каждом ответе на прием данных сообщается также сколько еще данных осталось в окне, если окно забилось, то время от времени посылаются данные 0 длинны чтобы как только окно освободилось можно было дослать очередной кусок. Так же есть дополнительное автономное сообщение которое сообщает что окно освободилось.
принимаются данные в окно, как только вы обработали данные, вы их из окна извлекаете. Есть разные реализации освобождения окна, в кейле она единовременная на все окно.
то есть допустим у вас окно 10, приняли 6 байт, окно стало 4,
обработали 6 байт, сбрасываете окно и оно становится опять 10. Если вы обработали 2 байта, то у вас нет возможности извлечь только их сделав окно 6, пока все 6 не обработаете окно не освобождаете.
как только вы приняли 6 байт, больше 4 вам прислать не могут, как освободили окно может придти все 10 сразу. Чем больше окно - тем больше надо памяти, но тем быстрее работает стэк.
Огромная благодарность Golikov A! Разобрался, все пока понятно и отлично работает. Далее самое интересное. Как показать веб-страничку и с нее настраивать прибор? В часности нужно со странички сообщать прибору числовые значения для рассчетов. Есть нужда задавать коэффициенты полинома и т.п., отображать на страничке некоторые служебные значения а-ля телеметрия. Ну и просто отсылать команды для принудительного переключения в интересующие режимы. Собственно как показать страничку и устроить диалог с прибором? Спасибо.
Golikov A.
Dec 24 2013, 08:56
собственно поднять HTTP сервер

как еще то

?
HTTP сервер это дополнительная надстройка над ТСР, собственное следующий уровень протоколов. Но тут я уже не силен, я такое не практикую, у меня подключение по сокетам по своим каналам, так как мои клиенты - это наши же программы, и протоколы у нас закрытые.
А как можно программно менять адрес и порт? Как потом программно актуализировать изменения?
kolobok0
Dec 24 2013, 10:45
Цитата(smk @ Dec 24 2013, 13:29)

А как можно программно менять адрес и порт? Как потом программно актуализировать изменения?
А порт нафик менять? Если у вас хост является Вашей железкой? Типа можете забыть и заюзать под другие дела порт?
Или я не понял вопроса?
Для задания адреса - либо инициализация его через дисплей, флэшку или ышо какой удобный способ(хоть джамперами набирай

).
Либо ышо просче - поднять DHCP.
По поводу передачи запросов посредством HTML-я: копайте запросы GET и POST.
Цитата(kolobok0 @ Dec 24 2013, 12:45)

А порт нафик менять? Если у вас хост является Вашей железкой? Типа можете забыть и заюзать под другие дела порт?
Или я не понял вопроса?
Изделие изготавливается с установками по умолчанию, а у заказчика настраивается сообразно ихней конфигурации сети. Порт менять не очень-то нужно, но бывали случаи когда настроенное ПО у заказчика использовало другой порт.
Golikov A.
Dec 24 2013, 11:10
IP адрес можно менять на лету.
заполняете структуру localm и все, вы работаете сразу на новом IP.
смена порта требует пересоздание сокетов.
у нас реализовано 2 варианта.
1. Бутлоадер.
Грузиться с дефолтными настройками, с закрытыми сокетами. Запрашивает по DHCP новый адрес, если не получает грузиться с дефолтным адресом. Пользователь по UDP имеет возможность заменить IP адрес, и задать порт, так же по UDP подает команду на создание ТСР сокетов с указанным портом.
2. Штатная программа, все настройки сохраняет во флэш, там хранятся номера портов, IP адрес по умолчанию, режим работы с DHCP или без. Эти настройки можно менять через UDP и сохранять. После загрузки все ТСР сокеты сразу создаются, если надо сменить порт, меняем, сохраняем, и перезагружаем устройство.
для UDP порт не меняемый, и всегда один.
С рестартом наверно самое правильное решение. Если заработает на столе, то и на производстве не подведет.
Сделал как написано в:
http://we.easyelectronics.ru/LPC/lpc1768rt...eb-updated.htmlВсе вроде как собралось, но при обращении получаю не свою страничку, а такое:
Код
HTTP 1.0 404 Error. File Not Found
The requested URL was not found on this server.
Что я делаю не так?
kolobok0
Dec 24 2013, 18:26
Цитата(Golikov A. @ Dec 24 2013, 15:10)

...по UDP имеет возможность заменить IP адрес...
кхм. в таком случае пару вопросов:
это в одном сегменте или грамотный перебор мостов-шлюзов?
критерий тогда удалённости каков, и как долгий процесс(если не один сегмент) сканирования?
Цитата(smk @ Dec 24 2013, 22:02)

..при обращении получаю не свою страничку, а такое:
Код
HTTP 1.0 404 Error. File Not Found..
..
это значит, что по данному адресу страничка не найдена. ответ отдал сервак.
т.е. алгоритм следующий...
выясняете работоспособность вашего девайса, уровень ICMP эхо запрос-ответ. => юзаете команду ping
юзаете с разными хитрыми параметрами - читайте справку к ней. особенно уделите внимание сборке на IP уровне.
если всё ништяк(полезно так же смотреть на нижнем уровне что получаете на уровне пакетов), дальше запрашиваете страничку по 80 порту.
смотрите на нижнем уровне такие вещи как
1) приход нефргаментированных IP пакетов (теоретически потом могут появится, если запросы на сервак будут не слабыми).
2) коректность сессии TCP
3) отдача HTML кода.
если где затык - разбираетесь с данным уровнем.
по идее в железке надо открыть порт на котором вы будете ждать запросы на вэб сервак(по умолчанию 80 порт - не SSL), и при запросе
вида GET HTML отдать "файл" размеченный вэю страницей.
всё дело контролируете на нижнем уровне снифером, и ышо смотрите что получает броузер (правая кнопка, просмотреть содержимое HTML).
сравниваете что отослали и что получили.
где то так
Обратил внимание на такую штуку. Я меняю содержимое файла index.htm добавляя текстовые строки. По идее размер кода должен расти, но он не меняется вообще. Что бы это значило?
Golikov A.
Dec 24 2013, 20:17
UDP тем и хорош что имеет широковещательный режим, именно потому он и выбран для поиска. Посылается запрос специализированный на спец порт широковещательно, наши устройства обрабатывают и отвечают. Далее уже по обстоятельствам.
В целом мы можем потребовать достаточно специфичную конфигурацию сети, так что world wide мы не реализуем, не далее чем пройдет широковещательный запрос - ответ.
Пингуется, принимает и предает все как задумано. Только свою страничку не могу показать. При этом страничка с ошибкой 404 нормально показывается. Мгновенно практически. Исходя из того, что сообщает об отсутствии файла index.htm и модификация файла не приводит к изменению размера кода делаю вывод, что страничка действительно не прикручена, хотя компилятор ее видит и обрабатывает. В web.c не наблюдаю ничего похожего на html-код. Как правильно прикрутить свою страничку?
smk, уже давно смотрел примеры, могу что-то путать, но, по-моему, там какой-то утилитой исходное переколбашивалось в С - char[] - массив
посмотрите, нет ли в каком-нить из файлов исходников большого массива
Цитата(aoreh @ Dec 25 2013, 15:02)

smk, уже давно смотрел примеры, могу что-то путать, но, по-моему, там какой-то утилитой исходное переколбашивалось в С - char[] - массив
посмотрите, нет ли в каком-нить из файлов исходников большого массива
Переколбашивает, но размер прошивки не меняется. Вот что озадачивает. И ладно бы, но и страничку тоже не показывает. Может выложить архив с проектом?
Путем сопоставления с демо-проектом кое-что подправил (ну да раньше с того и начиналось). Теперь размер файла (массива) меняется в зависимости от наполнения странички. В целом уже подвижка. Однако всеравно не показывает ее. Что можно еще смотреть? Буду рад любой подсказке.
Можно меня поздравить. Заработало. Причина была в том, что в свойствах файла в пути к нему стояли большие буквы, а на самом деле в названии директории только первая была большая, а остальные маленькие. Как так вышло я не знаю, возможно что-то прохлопал.
Теперь нужно сделать кнопку на сайте и окошко и меняющейся цифиркой из контроллера.
Подключил файл HTTP_CGI.c и при попытке компиляции получил ошибку:
Код
HTTP_CGI.c(251): error: #70: incomplete type is not allowed
Как с ней бороться, подскажите пожалуйста. Спасибо.
Цитата(smk @ Dec 25 2013, 21:29)

Можно меня поздравить. Заработало. Причина была в том, что в свойствах файла в пути к нему стояли большие буквы, а на самом деле в названии директории только первая была большая, а остальные маленькие. Как так вышло я не знаю, возможно что-то прохлопал.
поздравляю

я когда только перешел на линукс часто так "прохлопывал", жертва майкрософта
kolobok0
Dec 25 2013, 21:35
Цитата(smk @ Dec 25 2013, 21:29)

..Можно меня поздравить. Заработало....Теперь нужно сделать кнопку на сайте и окошко и меняющейся цифиркой из контроллера.
проздравляю! ик!
Кнопка - то понятно как. Либо замаскированный якорь, либо форма ввода, либо всякие скрипты у клиента.
апдэйт - то либо встроенный фрэйм с прописыванием времени апдэйта, либо скрипт на апдэйт этой переменной и показом.
надеюсь не обшибся, в этой текстовой разметке

а лучше - сбегайте на форумы всякие посвящённые этим делам.
к примеру:
php.ru форумышо один не плохой форумТам смотрите соответствующий раздел про HTML и иже.
Код
HTTP_CGI.c(251): error: #70: incomplete type is not allowed
Так может кто-то подскажет как с такой ошибкой бороться? Прикрутил файл HTTP_CGI.c и при компиляции получил с десяток таких сообщений.
Golikov A.
Dec 26 2013, 17:26
как прикрутили то?
поищите по тексту, может он у вас где дефайном объявлен, вернее есть дефайн который из этого имени что-то делает.
в кейле ctrl + shift + f
и туда HTTP_CGI.c
если вы его инклюднули, то это пипец, он же СИ а не хедер.
ну и не плохо поглядеть что там на 251 строке написано, может там чего не хватает легкого...
или может он Сишный, а у вас СРР проект, тогда надо писать
external "C"
{
}
или наоборот...
Цитата(Golikov A. @ Dec 26 2013, 19:26)

как прикрутили то?
Просто добавил в проект. При этом в демо-проекте он точно также добавлен для обработки CGI запросов в HTML. однако там компилирется без проблем, а у меня есть вон те ошибки и много. Почему?
Цитата(smk @ Dec 26 2013, 21:55)

Просто добавил в проект. При этом в демо-проекте он точно также добавлен для обработки CGI запросов в HTML. однако там компилирется без проблем, а у меня есть вон те ошибки и много. Почему?
так а что там, в той строке, на которую ругается?
Golikov A.
Dec 26 2013, 20:50
ставлю на то что CPP проект и сишный файл, или наоборот...
andrewlekar
Dec 27 2013, 05:19
Ставлю на то, что макрос неправильно развернулся, так как от другой версии компилятора.
я бы поставил на то, что есть форвардная декларация, но нет полного определения (на момент использования)
или определен массив без указания размера, но пытаются использовать его sizeof.
Если я попрошу посмотреть проект чтоб определиться, может не откажите в помощи? Сам я врядли что-либо смогу определить. Буду очень признателен. Спасибо.
Нажмите для просмотра прикрепленного файла
О! похоже, я таки угадал!
там в 251 строке используется
http_EnAuth
в свою очередь это дефайн
#define http_EnAuth http_config.EnAuth
а вот объявление переменной:
extern struct http_cfg http_config;
но я нигде не нашел ни http_cfg ни самой http_config
возможно, они где-то в либах, которых не приаттачено к проекту, точнее http_config в либах, а struct http_cfg в невключенном хидере
но каких-то внешних нестандартных include не видно
а кроме самой ошибки еще что-то есть? какие-нибудь ворнинги?
сам проект скомпилить не могу, кейла у меня нет
Нет, другого ничего нет. Только с десяток таких ошибок по разным строчкам.
Цитата
но я нигде не нашел ни http_cfg ни самой http_config
Я тоже не нашел. Есть только net_config.c
Цитата(smk @ Dec 27 2013, 12:42)

Нет, другого ничего нет. Только с десяток таких ошибок по разным строчкам.
Я тоже не нашел. Есть только net_config.c
тааак... нашел инсталляцию кейла
нашел в хидерах эти определения в файлах
rl_net_lib.h net_config.h
полный путь
c:\Keil\ARM\Pack\Keil\MDK-Middleware\5.1.3\Network\Include
поскольку сам не пользовал, как это пользовать не знаю, но, скорее всего у вас просто где-то не подключен вот этот net_config.h
ПС. да, похоже он перетащен прямо в проект, но сам по себе старый, т.е. как кто-то предполагал разные версии либ, хидеров и примеров
Golikov A.
Dec 27 2013, 11:43
в проекте
#include "net_config.h" "RTL.h" и подобное
меняйте на
#include <net_config.h> <RTL.h> и подобное
из проекта выкидывайте все хедеры что связаны со стэком, оставляйте только
net_config.c и прочие сишники.
библиотеку к проекту подключайте, и все соберется...
Сделал как советовали. Повыкидывал, скобки поменял. Файл библиотеки подключил из кейловской директории, в свою не копировал. Из своей удалил. Пробогвал собирать - тоже самое. Теже сообщения. А что у Вас собралось?
Golikov A.
Dec 28 2013, 13:04
ну у меня возникли какие то траблы с web.inp
и у меня небыло LEDrun
LEDOut
я это все покоментил,
заменил файл библиотеки на свой, потому что у меня версия не 454, и все собралось...
LEDrun LEDOut у меня тоже нет. Может мне 4.72 тоже поставить? Фирменный программатор купил, уже можно.
в HTTP_CGI.c есть такие строки:
Код
/* Net_Config.c */
extern struct tcp_cfg tcp_config;
extern struct http_cfg http_config;
так вот где оно все не ясно. так и не нашел. А у Вас оно есть?
Посмотрел демо-проект. Там такого нет вообще.
Golikov A.
Dec 28 2013, 14:23
есть в net_lib.c
CODE
TCP_CFG tcp_config = {
tcp_scb,
TCP_NUMSOCKS,
TCP_MAXRETRY,
TCP_RETRYTOUT * TICK_RATE,
(200 + TICK_INTERVAL - 1) / TICK_INTERVAL,
TCP_SYN_RETRY_TOUT * TICK_RATE,
TCP_INIT_RETRY_TOUT * TICK_RATE,
TCP_DEFTOUT,
TCP_MAXSEGSZ,
TCP_RECWINSZ,
TCP_CONRETRY
};
HTTP_CFG http_config = {
http_scb,
HTTP_NUMSESS,
HTTP_ENAUTH,
HTTP_PORTNUM,
HTTP_SRVID,
#if (HTTP_ENAUTH)
HTTP_AUTHREALM,
HTTP_AUTHUSER,
http_passw
#else
"","",""
#endif
};
это объявления
в нет конфиге у меня только дефайны и обработчик ошибок.
в моем проекте HTTP_CGI.c нету, а в вашем, если они были в архиве, то есть, я в этом файле ничего не менял.
Только вот с вашей бибилиотекой у меня не нашлась куча фукнций и определений, когда заменил на свой файл библиотеки сразу полегчало и все нашлось...
мне кажется у вас несовпадение файла библиотеки и заголовков, возьмите файл из кейла тот что соответствует заголовкам. И второй момент, ваш проект что вы нашли мог быть под новый стэк, и тогда тоже может не работать на библиотеке от более старого стэка.
Да вроде бы с нуля все делал. На машине действительно есть 4.21 версия. Наверно снесу обе и поставлю 4,72. У Вас 4,72 или 4,72а?
Golikov A.
Dec 28 2013, 17:48
4.72.10.0
кстати в ней в стэке появился какой то промежуточный буфер, теперь частота вызовов call_back функции 5 мСек, а раньше была 1 мСек... вот такие вот дела. Общая скорость передачи данных не изменилась, а вот скорость реакции упала маленько... хоть на LwIP переходи обратно....
Не думаю чтоб в моих приложениях это было критично. На сегодня если я за секунду успею раз 100 отдать буфер в 1кБ, то устроит. Интересно, но получается более 200 пакетов за 1 сек не отправить. Так? даже наверно меньше.
Golikov A.
Dec 28 2013, 20:28
получается так... То есть если пакеты маленькие то и скорость здорово падает...
Поставлю 4.72 без а. Все едино как сделаю на кейловском стеке, по плану все повторить, но с Lwip.
Golikov A.
Dec 29 2013, 13:29
мы тоже решили что-то на LwIP перелазить. Хорошо работать с поддерживаемой библиотекой, в lwIP косяки все на тебя ложатся, но зато там гораздо больше контроль. Можно и 0 копировальный буфер сделать, и прочие радости...
С наступившим! И так 4,72 я поставил. Прешние проекты компилируются без проблем. Хотелось бы продолжить.