megainformatic - статья Тимонина Андрея - DirectX9. Создаем основной класс обработки графики.
[к содержанию] [другие статьи Тимонина Андрея]
DirectX9. Создаем основной класс обработки графики.
автор: Тимонин Андрей
дата публикации на сайте Мега Информатик: 18.11.2012
Был найден более подходящий пример для решения задачи,
которая стояла передо мной.
c:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\winsock\simple
Его мы и будем изучать далее.
А еще у меня в ходе работы возникла такая мысль:
всё что я делаю - это документирую свою деятельность в форме статей.
Если бы кому-то из непрограммисткой области пришло на ум задокументировать
какие-то свои действия и выложить на всеобщее обозрение, то
это выглядело бы по-меньшей мере странно. :)
Представьте, работник автосалона пишет:
Пришел на стэйшн, сделал то-то и то-то, чтобы раскрутить клиента
на покупку того или иного авто. И т.д.
Хотя идея, кстати говоря, не такая уж и странная.
Другие работники этой отрасли усвоив такие знания смогут
таким образом достичь каких-то результатов.
Правда в программировании результат всегда точно определен.
Это либо работающая программа делающая действия по решению
четко поставленной задачи, либо не делающая её.
Конечно с покупкой или не покупкой такой программы результат
более чем размыт.
Т. е. разработка программ и их продажа - это совершенно разные
отрасли деятельности, требующие и разных познаний, навыков
и инструментов (читай программ).
И если в программировании опять же всё более-менее ясно -
хотя бы с точки зрения получения результата на уровне: Да - получилось
или Нет - не получилось.
То в продажах царит нечто напоминающее (с моей конечно точки зрения)
"танцы с бубном".
Конечно же с точки зрения непосвященного деятельность программиста -
это точно такие же "магические заклинания" и "танцы с бубном".
Но и в той и другой отрасли результат легко оценить: если программа
работает - то она дает ответ на поставленные вопросы.
Если продукт продан и прибыль получена - то это тоже очевидно.
Другой вопрос, на тему которого мне бы тоже хотелось порассуждать, как это сейчас
модно во всяких ток-шоу, так это попытка расценивать деятельность
менеджеров и программистов на уровне того же самого программирования.
Но увы. В силу определенных причин такая оценка всегда крайне субъективна -
хоть, как говорится, результат и можно оценить как Да/Нет -
но эти самые Да и Нет крайне размыты и зависят от личных качеств субъекта
который решает что оно Да или что оно Нет.
Если программа работает и дает успешный результат - это конечно Да.
Но никто не знает о её скрытых дефектах и возможности развивать программу
в будущем. Там существует целый комплекс вариантов: начиная от такого
когда в силу своих особенностей и опыта разработчика программу модифицировать
очень легко, до полной противоположности - когда легче написать новую программу,
чем разбираться во всех сложностях и тонкостях её реализации.
Обычно тот, кто считает себя квалифицированным видя перед собой какое-то
сложное решение, почти неглядя выбирает второй вариант.
Таким образом на первый план выходят не знания, а такая составляющая
как доверие к разработчику.
Если есть уже проверенные временем решения, которые этот разработчик выпустил,
то обычно, с новыми задачами или с доработкой каких-то проблемных задач идут к нему.
Если же такого нет - полагаются на случай.
И вот когда проект попадает в область, когда не совсем понятно кто виноват
в невозможности его завершения, тут всё завершается очень трагично.
Конечно может не совсем уж так трагично, но всё-таки и не совсем приятно.
В любом случае, один рабочий поток разработки завершается и начинается какой-то
совершенно другой. Но это уже совершенно другая история и она того, кто попал
под "каток" совершенно уже не интересует. А если и заинтересует, то только
с точки зрения "был ли я прав или нет ?". Под правотой понимается конечно уровень
квалификации, но всё можно списать на что угодно.
На нехватку финансирования, выделенного времени и т. д.
Одним словом люди с неудачным опытом совместного сотрудничества на уровне
"заказчик-исполнитель" просто расходятся в стороны и ищут каких-то новых вариантов.
Вот и всё.
Я конечно же всегда придерживаюсь мнения: на разработку нужно тратить столько времени,
сколько просит разработчик, а не ограничивать его.
Если будут какие-то ограничения - с финансовой стороны, либо со стороны временных рамок,
либо, что чаще и бывает - и с той и с другой стороны, да еще сдобренной хорошей порцией
сложностей в самом проекте и поставленных задачах, то если Ты только начинаешь работать
с таким проектом - впору задуматься: а стоит ли браться ?
Хуже бывает если выбора уже нет, и всё может окончиться отрицательным результатом и
отрицательным опытом сотрудничества.
К сожалению или к счастью - программирование и разработка чего-либо, каких-либо программ и
изучение связанной с ними предметной отрасли, это деятельность которая сложно поддается
однозначной оценке. Оценки и результаты могут быть самые крайне противоположные от:
легко и дешево, до сложно и дорого со всеми возможными комбинациями вышеупомянутых и
их различными варриациями представляющими смесь того и другого.
И всё зависит от:
квалификации разработчика,
способности адекватной оценки результата со стороны заказчика
и
конечно же доступного бюджета и временных рамок.
В каких-то других, уже более-менее устоявшихся отраслях и сферах деятельности всё
уже более-менее устоялось и цены, время, опыт уже более-менее, но хорошо известны
и легче поддаются оценке.
Примеры ?
Да вот навскидку: услуги по перевозу грузов или пассажиров; оказание услуг в образовательной
сфере; концертная деятельность; розничная продажа товаров;
А в программировании ?
Заказчик порой может придумать что-то немыслимое. Не имея даже малейшего представления
как это реализовать и вообще возможно ли это. Он просто где-то что-то услышал-увидел-ему
подсказали.
И вперед.
Дальше начинается кино.
Под названием поиск исполнителя, который сможет за бросовый бюджет и короткий срок эту идею
поставить на ноги.
Если идея более-менее программно реализуемая - то конечно результат рано или поздно будет
получен.
Но чем сложнее идея, тем сложнее и тернистее путь заказчика, который решил, не своими руками,
всё это реализовать.
А почему не своими ? Не хватает знаний, опыта, времени. Но в то же время есть свободные
средства и чаще всего постановка задачи от какого-то начальства свыше.
Тогда и начинается новое кино.
Вера в то, что всё будет хорошо, даже если всё плохо, спасает нас. Это надежда на лучшее
и на то, что всё меняется к лучшему.
Модель её использования очень проста: зачем ругаться и мучать друг друга, когда можно всё
решить мирно и спокойно ?
Если задача решается - проявляем к этому минимум восторгов, если НЕ решается - минимум
досады и разочарования. И никаких поспешных выводов и решений. Иначе всё дело можно
загубить на корню.
Это инструкция и для тех кто ищет задачу или проект и для тех, кто таковые предлагает.
Напишите себе плакат и повесьте на самом видном месте, чтобы видеть и читать это каждый день:
Искреннее и доброжелательное отношение - вот ответ на любые вопросы и любые проблемы,
которые будут решаться в этом случае как бы сами собой.
Почему так ?
Да потому что всегда тот кто хочет найти, находит. А тот кто напротив, изначально дал
себе установку на отрицательный результат - его и получит в итоге.
Не будьте врагами сами себе !
Тот кто привык что-то ругать и критиковать, в итоге и получит лишь ответную ругань и
критическую болтологию.
Тот кто настроен на креативное русло - достигнет и созидательных результатов. Неважно каких -
отрицательных с точки зрения того, кто их будет оценивать и принимать или положительных.
Помните - любые оценки - это известная доля субъективизма, а потому не ищите позитива там,
где сами плодите и порождаете негатив.
Начинайте изменяться начиная с прямо сейчас и прямо с себя. И только потом уже глядя
по-сторонам.
И да, запомните наконец, эту простую истину -
Искреннее и доброжелательное отношение - вот ответ на любые вопросы и любые проблемы,
которые будут решаться в этом случае как бы сами собой.
Любая неудача переносится легче, если это искренне и без злобы и лишнего, излишнего
негатива.
Любой успех однозначно определяется заранее позитивной оценкой и настроем на результат,
даже если задача заведомо кажется нерешаемой или в ходе работы выясняется таковое.
Решение всегда есть, его всегда можно найти. Но имеется в виду такое - которое
даст положительный результат, а не отказ от работы или откат от проблемы.
Положительное и позитивное возникает только там, где не ищут позитив днём с огнём,
а где это уже устоялось и считается за норму.
Только так и никак более.
Простите, но увы, я не даю рецептов, на гарантированные результаты.
Они всегда рождаются в труде и в борьбе. Сказать всегда проще, чем
сделать.
Будьте всегда людьми не только слова, но и дела.
Не воспринимайте всё вышесказанное как простую формулу или рецепт.
Ошибка именно в том, что всё пытаются воспринимать просто и "КАК ЕСТЬ".
На самом деле не всё "ПРОСТО" и не всё следует понимать "КАК ЕСТЬ".
Забудьте про такие стереотипы.
Искать позитив и генерировать его это не одно и то же.
Здоровое зерно будет расти только на здоровой почве. Даже если Вы заранее
ложите в почву здоровое зерно, не надейтесь просто на то, что раз
оно здорово, то и плоды его тоже будут здоровыми. Почва тоже должна
быть здоровой, а если нет - то должна быть оздоровлена.
Так и человек. Не может генерировать или воспринимать позитив, если
сам он изнутри не позитивен. Это будет лишь притворство и ничего
более.
Путь этот труден и извилист.
Вы наверное уже устали от такого "менторского" и "назидательного" стиля.
Умных мыслей и установок.
Добро и зло существуют и сосуществуют в тесной связи и взаимозависимости.
Одно не может быть без другого. Как день без ночи и наоборот.
Одно перетекает в другое, плавно и не плавно, существуют и сосуществуют
самые разнообразные его формы и виды. Мыслимые и немыслимые, очевидные
и совсем мало распространенные, даже уникальные, маниакальные и
малоизученные.
Носителей настоящей истины нет. Всё решается в конкретных обстоятельствах.
Насколько обыденно и банально бы это не звучало, но сказав всё вышеуказанное,
усвоив его, всё равно знайте, что всегда есть и будут и другие
варианты правильного пути. Другие мнения и решения.
И никакое из них не будет являться истиной в последней инстанции.
Потому что её нет и быть не может.
Всё применимо только в конкретных условиях и обстоятельствах и результат
и его достижимость, и достижение результата.
Почему мы не живём вечно и нам кажется, что мы делаем что-то уже бесконечно ?
Мудрость.
Она не приходит сразу и ко всем.
Мудрыми становятся и остаются также не сразу и не все.
Все мы разные.
У каждого из нас свой путь.
Свои трудности и проблемы.
Но и свои радости и достижения.
Нет такого человека, который бы был АБСОЛЮТНО СЧАСТЛИВЫМ.
Счастье достигается тем, что постоянно его надо искать и есть неиссякаемая
надежда на то, что Мы его найдём !
На этом пожалуй я закруглюсь.
Простите если утомил Вас своими философскими или какими-либо еще высказываниями.
Просто вылилось, как говорится.
Видимо хотелось сказать и оно свершилось.
Далее мы будем работать более предметно и опять
займёмся вышеуказанными вопросами.
Итак пример
c:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\winsock\simple
Пример включает 2 приложения:
simples - т. е. simple Server
и
simplec - т. е. simple Client
Оба приложения являются консольными. Выполнив их сборку в среде MSVS 2005 или выше
Вам нужно будет запускать их из окна коммандной строки Windows, чтобы
увидеть результат их работы.
Если любой из примеров запустить с параметром тире -
simples -
simplec -
То будут выведены возможные параметры коммандной строки для запуска данного приложения.
cd C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\
netds\winsock\simple\server\Debug
C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\winsock\simple\server
\Debug>simples -
Usage
simples -p [protocol] -e [endpoint] -i [interface] [-4] [-6]
Where:
-p protocol - is one of "TCP" or "UDP"
-e endpoint - is the port to listen on
-i interface - is the string local address to bind to
-4 - force IPv4
-6 - force IPv6
Defaults are TCP,5001 and INADDR_ANY and IN6ADDR_ANY (if IPv6 present)
Кстати, чтобы не набирать в коммандной строке длинные строки, можно один раз набрать их
в текстовом редакторе, например в Блокноте, а потом просто копировать и вставлять
в окно коммандной строки.
Для примера я запустил сервер с такими параметрами
C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\winsock\simple\server
\Debug>simples -p TCP -e 80 -i 127.0.0.2
socket 0x7c bound to address 127.0.0.2 and port 80
Т. е. задал для сервера использование протокола TCP, подключил к порту 80 и привязал к
ip - 127.0.0.2
Сервер работает и остается в памяти пока не будет нажата комбинация клавиш [Ctrl] + [C].
Он ожидает запросов от клиента.
Клиент, это приложение simplec.
Запускается с такими параметрами -
simplec -p -n -e -l
Значит надо указать те же параметры, что были указаны у simples, чтобы клиент мог успешно
подключиться.
simplec -p TCP -n 127.0.0.2 -e 80 -l 10
Запуск simplec с указанными параметрами осуществляем в отдельном окне коммандной строки
Windows.
C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\winsock\simple\client
\Debug>simplec -p TCP -n 127.0.0.2 -e 80 -l 10
Client attempting connection to: 127.0.0.2 port: 80
Connection established...
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 0]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 1]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 2]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 3]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 4]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 5]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 6]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 7]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 8]] from server
wrote 40 bytes
read 40 bytes, data [This is a small test message [number 9]] from server
Отправка/получение тестовых данных происходит 10 раз подряд (циклически), поскольку
я указал при запуске simplec параметр -l 10.
Как работает сервер simples Мы рассматривать здесь не будем, т. к. это не
нужно для моей непосредственной задачи. У меня серверная часть реализована не на
c++, а на php.
Вы, при желании и наличии такой необходимости, можете сами изучить исходный код
simples взяв его из Windows SDK 7.0.
О том, где скачать его и как с ним работать я уже рассматривал ранее.
Как лучше к этому подойти Вы сейчас и узнаете на примере изучения simplec.
Основная проблема с которой Вы возможно столкнетесь, по крайней мере с ней
сталкивался я, это работа со строками.
В примере simplec используются обычные символьные строки char. Но большинство
Windows - приложений работают с unicode.
Для работы с unicode, а точнее чтобы от него не зависеть, нужно использовать
так называемые generic строки - там где вы явно задаете строку применять оператор _T
CString cs_str = _T("Simple string sample");
Если указывать L
CString cs_str = L"Simple string sample";
То сразу будет использоваться unicode, независимо от кодировки, которая задана в настройках
проекта.
Если же использовать _T - то в зависимости от настройки проекта будут применяться либо ANSI
строки, либо unicode.
В большинстве приложений Windows всегда используется unicode. Но на низком уровне, с которым
работает
Windows Sockets 2 ведется работа с каждым байтом информации отдельно. Поэтому вопрос
кодировки
и преобразований из одной кодировку в другую очень важен, и когда Вы будете разрабатывать
свои приложения с использование Windows Sockets 2 API, то волей-неволей столкнетесь
с проблемой
использования строк и их различных видов.
Основные ошибки какие могут быть - это утечки памяти - memory Leaks и Access Violation.
Когда какая-то память выделяется, но
не освобождается, или идёт обращение к участку памяти, в непредусмотренном адресном
пространстве.
Как добиться наилучшего понимания ? Вам нужно будет плотно работать с приложением в
режиме отладки Debug, а также писать небольшие простенькие прилоежния - я их называю
ТЕСТОВЫЕ. В таких приложениях по возможности размещаем проблемный код.
Если он связан с другим кодом, упрощаем его так, чтобы он получился как можно
меньшим. Там где, например подразумевается выполнение какого-то большого блока
кода для получения заранее предвиденного результата - просто используем
готовое значение для подстановки - тогда можно будет и не включать в ТЕСТОВОЕ
приложение этот БОЛЬШОЙ КУСОК кода.
В тестовых приложениях можно экспериментировать - чтобы лучше понять ту или
иную особенность, которая не совсем понятна или вызывает ошибку.
Поскольку вариантов работы может быть множество, а правильный, естественно
никто вам не укажет, нужны будут собственные эксперименты с кодом.
И без ТЕСТОВЫХ приложений тут никак не обойтись.
Приведу небольшой пример, который продемонстрирует какие вопросы
могут возникать и как они решаются опытным путём.
Документация и мануалы всегда дают какой-то пример, но чтобы
его лучше понять нужно писать собственный код и экспериментировать.
Например у нас объявлена символьная строка char -
char hoststr[NI_MAXHOST],
NI_MAXHOST это системная константа равная 1025.
Чтобы очистить строку от неинициализированных данных применяем функцию -
SecureZeroMemory(&hoststr, sizeof(hoststr));
Но может возникнуть 2 вопроса:
Почему &hoststr, а не просто hoststr ?
Т. е. так -
SecureZeroMemory(hoststr, sizeof(hoststr));
И почему sizeof(hoststr), а не strlen(hoststr) ?
Т. е. так -
SecureZeroMemory(hoststr, strlen(hoststr));
Такой код -
SecureZeroMemory(&hoststr, sizeof(hoststr));
Будет правильным, только если строка определена как
массив элементов char -
char hoststr[NI_MAXHOST],
Но если имеется такой массив -
char *hoststr = "localhost";
Или
char *hoststr;
Когда строка формируется динамически и её длина может быть любой в допустимых
пределах.
В этом случае - char *hoststr - это уже не массив, а указатель на массив и очищать его
нужно не так -
SecureZeroMemory(&hoststr, strlen(hoststr));
А так -
SecureZeroMemory(hoststr, strlen(hoststr));
Потому что &hoststr - так мы очистим не массив, т. е. не значения которые хранятся
в буфере строки, а значение указателя - он станет равным 0 или NULL. При
этом считается, что его память была освобождена.
И тут возникает сразу 2 ошибки:
1) Memory Leaks - утечки памяти - потому что указателю было присвоено NULL значение,
без предшествующего освобождения буфера оператором delete [] hoststr; //только
если буфер создавался динамически -
char *hoststr = new char[ request_str_symbols_count ];
request_str_symbols_count - подразумевается, что это некоторая числовая константа.
2) Поскольку hoststr был обнулен, то попытка обращения к нему вызовет ошибку
Access Violation - поскольку память уже недоступна в переменной hoststr.
И второй вопрос - о разнице между sizeof и strlen -
SecureZeroMemory(&hoststr, sizeof(hoststr));
SecureZeroMemory(&hoststr, strlen(hoststr));
Разница здесь в том, что функция sizeof - возвращает длину всей выделенной памяти для буфера
hoststr в байтах, а strlen возвращает длину строки hoststr - количество символов до первого
втретившегося символа \0.
Понятно, что когда hoststr еще только был объявлен, но не очищен, там содержатся
какие-то неинициализированные данные, т. е. по сути мусор. И неизвестно есть ли
там символ \0 - символ конца строки. А если и есть - то непредсказуемо - в какой позиции
он находится.
Так что выполняя команду
SecureZeroMemory(&hoststr, sizeof(hoststr));
Над буфером hoststr (буфер - это синоним строки - какой-то участок памяти, просто когда
мы говорим строка - то подразумеваем, что в памяти содержатся символьные данные
представляющие какую-то читаемую текстовую строку, но буфер в более общем смысле
может содержать любые двоичные данные - а не только текст), мы тем самым
инициализируем весь выделенный ей участок памяти нулевыми значениями.
Но команда -
SecureZeroMemory(&hoststr, strlen(hoststr));
Является логически неправильной, т. к. будет очищена в лучшем случае часть строки
до первого встретившегося 0 байта. Ну а может быть, что такого символа
вообще не окажется в неинициализированных данных, тогда hoststr останется
неинициализированной.
Конечно если строка уже была инициализирована - например туда уже было
помещено значение строки, тогда команда будет иметь эффект. Но опять же
очищен будет не весь буфер, а только часть его до первого символа
нуль-терминатора (т. е. \0 ).
Таких вопросов - на которые нет и не может быть ответов в мануалах
и доках, поскольку всех особенностей нельзя описать ни в каком
руководстве, будет у вас возникать при разработке очень и очень
много - почти на каждом шагу.
Например, от обилия таких вопросов, я даже спросил себя:
Ну почему, почему в C++ работа со строками так сложна и неочевидна,
не всегда ясно и понятно что происходит и почему возникает ошибка
в том или ином месте.
Ошибки как я уже говорил те же самые - Access violation и memory leaks.
Ответ звучит просто - возьмите язык php - он делался по-сути для
удобной работы со строками ! Потому что вся информация, которую
в php приходится обрабатывать и выводить - это, как правило,
строковые данные.
Так что, как видите, для работы со строками существует ЦЕЛЫЙ ЯЗЫК php !!!
Так что понятно, что c++ не может охватить всех нюансов, особенно
если Вы о них даже не знаете.
Поэтому не надо пенять на язык, а надо сжать зубы, запастись
терпением и дальше искать ответ на свои вопросы в тестовых
приложениях и экспериментах.
Теперь можно приступать к изучению кода -
c:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\winsock\simple\
client\simplec.cpp
Функция с которой начинается исполнение -
int __cdecl main
Сначала запустить сервер -
Открываем окно коммандной строки Windows - Пуск - Программы -
Служебные Windows - Коммандная строка
cd C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\winsock\simple\
server\Debug
simples -p TCP -e 80 -i 127.0.0.2
Не закрываем окно.
Теперь работаем с приложением клиентом - simplec
simplec -p TCP -n 127.0.0.2 -e 80 -l 10
Я буду запускать клиент из MSVS в режиме отладки,
поэтому эти параметры укажу в -
Command Arguments как описывалось на странице 4
-p TCP -n 127.0.0.2 -e 80 -l 10
c:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\winsock\simple\
client\simplec.cpp
Итак шагаем по коду в режиме отладки (как это делать тоже уже описывалось
на странице 4)
Сначала в цикле обрабатываются введенные агрументы коммандной строки -
// Parse the command line
if (argc >1)
{
for (i=1; i < argc; i++)
Отладочные значения могут оказаться такими -
address_family = 0
socket_type = 1
server_name = 0x007f4d6d "127.0.0.2"
//т. е. через параметр server_name мы задаем url по которому надо обращаться к серверу
//для решения вашей задачи можно подставить любой сервер,
для примера я использую megainformatic.ru
port = 0x007f4d7a "80"
//для megainformatic.ru также нужно будет использовать этот порт
maxloop = 10
//количество итераций отправки данных клиентом.
Небольшое отступление.
В чём отличие в применении символов & и * в языке c++ ?
Символ * - это указатель на адрес переменной, а не на её значение, если символ
звездочки применяется к параметру функции -
пример -
SearchCRLF(const char * strData, size_t data_length, size_t * found_at)
в данном случае переменные strData и found_at представляющие параметры
функции SearchCRLF будут указателями на адрес - или передаются по-ссылке
(имеют ссылочный тип).
strData при этом указывает на адрес массива из элементов типа char
Поскольку объявлена как
char * strData
Ключевое слово const означает, что данные указателя
являются неизменными -
т. е. изменяться внутри функции не будут (иначе это вызовет ошибку).
Таким образом, в операциях присваивания strData может находиться только
по правую сторону от знака =.
Необходимость ключевого слова const вызвана тем, что
если мы опустим его -
будет считаться, что данные в strData можно изменять.
Т. е. функция может изменить переданные по-ссылке в strData данные и strData
может находится в операциях присваивания как с левой, являясь приемником
значения, так и с правой - являясь его источником.
Поскольку все char строки являются массивами, то негласно считается, что
char * strData
и
char strData[100];
По-сути одно и то же - только в первом случае указатель является адресом
на блок данных, размер которого неизвестен, а значит может меняться
динамически.
Во-втором случае - блок представляет адрес на данные заранее известного размера -
из 100 символов (или байт), поскольку размер char - это размер 1 байта
в памяти.
Посмотрим на второй параметр функции -
size_t * found_at
прежде чем, попасть в функцию, параметр может быть определен так -
size_t search_result = -1;
//...
//и где-то дальше он передается в функцию
SearchCRLF(strData, strDataSize, &search_result);
Как видим при search_result появился значок &
Он как раз и означает, что в функцию будет передано не значение переменной search_result,
а указатель (адрес), по которому хранится данное значение.
Поскольку функция была объявлена так -
void SearchCRLF(const char * strData, size_t data_length, size_t * found_at)
{
//...
//то мы можем изменять значение параметра found_at тем самым вернув из
//нашей функции измененный результат
*fount_at = 0; //так мы изменяем значение параметра found_at переданного по ссылке
//(указатель на адрес как было указано выше)
}
Чем это отличается от варианта
void SearchCRLF(const char * strData, size_t data_length, size_t found_at)
{
?
А тем, что если параметр found_at передается по-значению, то внутри функции
мы его изменить не можем.
Таким образом, в операциях присваивания внутри тела функции,
он может появляться только с правой стороны -
void SearchCRLF(const char * strData, size_t data_length, size_t found_at)
{
//...
size_t some_var = found_at; //вот так
//а вот так мы его уже изменить не сможем - будет ошибка
found_at = 1;
}
Как видим в этом и состоит необходимость применения слова const для
строковых данных из символов char.
Для простых типов, таких как size_t - представляющих беззнаковое целое число,
применение оператора * автоматически подразумевает, что параметр
передается по-ссылке, а значит может быть изменен в теле функции.
Если * нет - значит передается значение.
В случае со строками это не является очевидным - строки в любом случае
представляют из себя массивы, а значит хранят указатель на адрес массива,
а не вереницу значений его элементов.
Поэтому когда мы указываем слово const -
const char * strData
Подразумеваем, что строка будет передаваться как бы "по-значению" и изменить
её будет нельзя.
Ну а когда const не указан - можно.
Вот такое небольшое отступление.
Далее мы продолжим изучение примера simplec.
Для решения стоявшей передо мной задачи нужна была всего 1 итерация.
Либо несколько - в случае ошибки соединения с сервером - это тоже
нужно будет предусмотреть и реализовать.
Далее всё идёт обычным порядком описанном в мануале по Win Sock 2
(где и как его прочитать я также упоминал в
Windows Sockets 2, ping, Windows SDK 7, чем открыть hxs файл - страница 4) -
// Load Winsock
if ((retval = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
//...
// Make sure the wildcard port wasn't specified
//тут убеждаемся не используется ли порт по-умолчанию - если задан 0 для него
if (_strnicmp(port, "0", 1) == 0)
Usage(argv[0]);
Для нас важен именно 80 порт т. к. simples я запустил именно с 80 портом
Да и megainformatic.ru также слушает этот - 80 порт.
retval = getaddrinfo(
server_name,
port,
&hints,
&results
);
//? определяется имя сервера если задан его ip и наоборот.
// Нужно будет проверить это задав сервер как megainformatic.ru
Если всё нормально и ошибок нет -
начинаются попытки коннекта -
while (addrptr)
{
conn_socket = socket(addrptr->ai_family, addrptr->ai_socktype,
addrptr->ai_protocol);
//...
retval = getnameinfo(
addrptr->ai_addr,
(socklen_t)addrptr->ai_addrlen,
hoststr,
NI_MAXHOST,
servstr,
NI_MAXSERV,
NI_NUMERICHOST | NI_NUMERICSERV
);
//ага, вот оно ! тут пытаемся получить данные если
//задано именно доменное имя
//...
// Make sure we got a connection established
if (conn_socket == INVALID_SOCKET)
{
printf("Unable to establish connection...\n");
goto cleanup;
}
else
{
printf("Connection established...\n");
}
Если ошибок нет - в консоль выведет Connection established...
Т. е. соединение успешно установлено.
Далее происходит самое главное и интересное, ради чего собственно всё и делалось -
//
// cook up a string to send
//
loopcount = 0;
for (;;)
{
//в буффер заносим некоторый текст, который будем передавать серверу
//в моей основной задаче этот текст - это запрос у сервера данных:
//например такой:
GET /?page=474 HTTP/1.1\r\n
Host: megainformatic.ru\r\n
Connection: Close\r\n
Таким образом, на примере приложения simple из Windows SDK 7
можно изучить все необходимые шаги для базовой работы с Windows Sockets 2,
аналог которого есть в языке php и называется fsockopen -
о нём я рассказывал в статье -
Работа с сокетами fsockopen из php
На этом ползволю себе закруглиться, т. к. более подробно
изучить пример simple Вы сможете сами - скачав Windows SDK 7.
видео-рассказ, уроки godot, виртуальный помощник по поиску информации
играть
читать
купить
скачать
игры Многоликий: dress - hordes эпизоды с 1 по 4
играть
скачать
купить
купить
игры, музыкальные клипы
скачать
скачать
смотреть
скачать/играть
музыкальный клип, игры
смотреть
играть
скачать
скачать
разработка игр, анимационный фильм, новогодняя дискотека 2020 - песни на итальянском, игра про лифт
смотреть
смотреть
смотреть
смотреть
игры, инструменты разработки, анимационный фильм, фильм.
купить
смотреть
смотреть
скачать
игры
скачать
скачать
скачать
купить
игры в браузере
играть
играть
играть
играть
игры в браузере
играть
играть
играть
играть
игры в браузере
играть
играть
играть
играть
игры в браузере
играть
играть
играть
играть
игры в браузере (3), создание музыки в браузере (1)
играть
играть
играть
играть
игры в браузере
играть
играть
играть
играть
игры в браузере
играть
играть
бк 0010.01 - играть!
играть
игры в браузере
играть
играть
играть
играть
игры в браузере (3), скачиваемые (1)
играть
играть
играть
скачать
игры в браузере
играть
играть
играть
играть
игры в браузере, скачиваемые игры
играть
скачать
играть
играть
игры в браузере
играть
играть
играть
играть
игры в браузере
Foxyland 2
quidget 2
играть
играть
полезный софт, игры в браузере
скачать
anova игра
A Knots Story
sabotage
сервисы, игры
24500 руб.
скачать
игра
играть
игры, программы
купить / скачать
купить
5500 руб.
скачать
поздравления, уроки рисования, уроки создания сайтов
читать
читать
читать
150 руб.
комиксы, музыка, рассказы
читать
читать
слушать
читать
игра для разработки, калькулятор услуг, cms, комикс
250 руб.
разработка на заказ
1250 руб.
350 руб.
игры для разработки, комиксы
скачать
читать
читать
скачать
игры шарики и ямки, комиксы про Костю Коробкина, ria xxl игра, fly snow 3d генератор эффектов снега, частиц и др. -
скачать
читать
150 руб.
350 руб.
Создай свою игру на fle game engine -
800 руб.
240 руб./скачать
скачать
скачать
Для создания сайта - модуль отзывов/комментариев для вашего сайта в составе megainformatic cms express files -
700 руб.
1250 руб.
150 руб.
500 руб.
Уроки Flash, бесплатные Flash - игры.
бесплатно
бесплатно
2500 руб.
14000 руб.
Поддержка сайтом нескольких языков (multi lang), создание собственной системы личных кабинетов, соц. сети или фриланс - биржи (megainformatic cms social), создание сервиса коллективных покупок на базе megainformatic cms groupon, онлайн сервис подсчёта статистики ключевых слов в статьях вашего сайта keywords gen + описание кода данного сервиса, с возможностью бесплатно реализовать его аналог на своём собственном сайте.
500 руб.
12000 руб.
14000 руб.
бесплатно
megainformatic.ru/webjob/ - сервис для фриланс проектов
- место встречи заказчиков и исполнителей
megainformatic.ru/webjob/ - сервис для фриланс проектов
- место встречи заказчиков и исполнителей
Системы управления сайтом, уроки
1250 руб.
бесплатно
550 руб.
500 руб.
megainformatic cms admin - простая и компактная система
для работы и управления сайтом
350 руб.
5800 руб.
3000 руб.
500 руб.
megainformatic cms free и серия продуктов - Уроки Photoshop
бесплатно
650 руб.
700 руб.
750 руб.
Данная серия посвящена описанию приемов и методов создания изображений,
с помощью инструментария программы Adobe Photoshop. Кроме того, многие
описанные средства могут вам помочь при освоении и многих других программ
для работы с растровой графикой - GIMP, Corel Photo Paint и других.
бесплатные игры 2d и 3d, а также эмулятор Ну, Погоди!
300 руб.
бесплатно
бесплатно
бесплатно
Это серия распространяемых бесплатно игр. Вы не только можете поиграть,
но и скачать исходники, получив тем самым возможность внести изменения
в игру или создать новую !!! (эмулятор Ну, Погоди! распространяется платно).
серия игр про Веселого Буквоежку, и бесплатно распространяемая игра
Нечто: Необъяснимое - в плену желаний
350 руб.
510 руб.
fle game engine
бесплатно
Здесь представлены новинки жанра - Говорящий Комикс, Настольная игра,
А также продукт, который позволит Вам научиться создавать игры самостоятельно.
Ну и конечно изюминка в своём роде - бесплатная игра - Нечто: Необъяснимое
- в плену желаний
Серия бесплатных онлайн уроков, посвященных 3ds max, photoshop, c++,
directx, delphi и php.
бесплатно
бесплатно
бесплатно
бесплатно
бесплатно
бесплатно
500 руб.
300 руб.
Описаны практические примеры решения различных задач, возникающих при
создании игр и сайтов.
Продукты Набор разработчика и Ваше Визуальное Шоу распространяются платно.
уроки и продукты различной тематики
бесплатно
бесплатно
бесплатно
400 руб.
Бесплатные Уроки Photoshop free, Бесплатные Уроки по программированию
на delphi directx - Как создать игру Ну, Погоди!, Бесплатная Авторская
музыка в формате mp3 - Музыкальные Миры, Платно распространяемый продукт
megainformatic cms express - система для быстрого создания Вашего сайта
на php + my sql.
Проекты игр, уроки
450 руб.
бесплатно
бесплатно
бесплатно
Игра Веселый Буквоежка, уроки delphi directx 8.1 для начинающих (описываются
основы 3d игр), моделируем девушку в 3d studio max, уроки музыки - пишем
музыку в Fruity Loops Studio
megainformatic
cms express files - это простое, быстрое и очень компактное решение
для создания первого вашего сайта. НЕ ИСПОЛЬЗУЕТ базы данных mysql.
Вместо этого используются файловые базы данных. Поэтому Вы
можете использовать систему даже на хостинге с поддержкой php, но
без поддержки баз данных my sql.
Очень
проста в установке - достаточно вам скопировать все файлы на ваш
хостинг и сайт готов к работе !!!
В комплект входят 3 готовых шаблона, модули поиска и карты сайта,
а также статьи по основам создания сайта.