На главную страницу
Форум txt.version   




Статья :: Примеры небольших программ

[Сygwin: среда для мультиплатформенного программирования]

Автор: m-me de Chapeau Claque

Дата:

    Немного лирики

    Доброго времени суток, уважаемый читатель! Я - новый автор статей для
сайта www.xakep.ru и, начиная с этой статьи, буду вести здесь цикл публикаций,
посвящённый вопросам сетевой безопасности и сетевого программирования платформ
Windows и UNIX.

    К сожалению (надеюсь, не для многих), я буду игнорировать всеобщую
любовь к Delphi и, нагло загиная привычную мне линию, буду вворачивать примеры,
написанные на классическом ANSI C (так называемый gnu style) и на ассемблере
UNIX'ового синтаксиса архитектуры x86. Однако, я попытаюсь искупить этот
грешок, снабжая исходный текст своих программ подробными комментариями. Ведь,
как говорил один мой знакомый, не самый последний человек в хакерском мире,
"главное - не знание языка программирования, а умение им воспользоваться!".
Очень рассчитываю на то, что этот аргумент сохранит меня от очень модной на
этом сайте деликатности тех самых немногих читателей :)

    Я программирую в среде cygwin, но это вовсе не означает, что всё, о чём
я буду рассказывать в своих статьях, действительно лишь для cygwin. Вы можете
пользоваться любым компилятором и любой средой, которой захотите. Вы можете
даже переписывать эти исходники на своём любимом языке в своей любимой среде.
Я не буду агитировать Вас за cygwin.

    Cygwin: что это такое?

    Cygwin - это аббревиатура от 'Cygnus', группы разработчиков свободного
ПО в рамках проекта 'RedHat' и 'Windows', всеми нами любимой операционной
системы. Спешу развеять очень популярную точку зрения, будто бы cygwin - это
эмулятор UNIX под Windows: это не так! Cygwin - это лишь мощный, очень развитый
и, самое главное, бесплатный набор программных средств переноса (портирования)
UNIX'ового ПО под Windows и кросс-компиляции (создания бинарного кода на одной
платформе под другую) UNIX'овго софта. Лично для меня, cygwin, прежде всего,
это мощнейший компилятор gcc с отшлифованными под Windows хидерами и либами.

    Cygwin нынче становится весьма популярным: многие производители
свободного ПО под UNIX поддерживать '--target=cygwin' в конфигах своих
программ, благо, это не столь трудоёмко. А cygwin, в свою очередь, расширяет
совместимость с UNIX, поддерживая не только posix, но и другие, более
узкоспецифичные стандарты UNIX-систем.

    Cygwin: где смотреть?

    http://www.cygwin.com - официальная страница cygwin'а, на которой Вы
сможете найти достаточное количество информации о текущем состоянии проекта, об
обновлениях cygwin'овских релизов, а также официальный список ftp-серверов,
периодично зеркалящих cygwin.

    Cygwin: что и как устанавливать?

    Зайдите на любое из зеркал cygwin'а. Вы увидите три основных
директории: contrib, latest и xfree. Первая - это программы, портированные под
cygwin самим Cygnus'ом и требующие для работы лишь доступности основной
библиотеки, cygwin1.dll. Третья - это портирование X-сервера под среду cygwin.
Нам понадобится содержимое второй директории, latest.

    Если Вы собираетесь программировать в cygwin'е, то для более-менее
комфортной работы Вам потребуются последние версии пакетов ash, autoconf,
automake, bash, binutils, bzip2, cygwin, diff, fileutils, findutils, gcc,
gperf, groff, gzip, less, login, m4, make, man, mingw, mingw-runtime, ncurses,
patch, sed ,sh-utils, tar, w32api, zlib и, естественно, setup.exe. Если Вы
маньяк, то можете выкачать исходники этих пакетов.

    По дефолту, cygwin встаёт в указанную Вами директорию в рамках тех
прав, которые Вы ему укажете. Установка cygwin'а создаст на рабочем столе свою
иконку и, щёлкнув по ней, Вы очутитесь в bash'е с весьма, на мой взгляд, мило
сконфигурированной цветовой гаммой.

    cygwin1.dll: что это такое?

    В библиотеке cygwin1.dll сосредоточен весь posix, который эмулирует
cygwin, а также некоторые особо важные функции cygwin'а. Грубо говоря,
cygwin1.dll - это самая главная библиотека cygwin'а, его kernel. Не забудьте
скопировать файл cygwin1.dll в любую директорию, к которой у Вас прописан
'PATH=', например, в '%windir%' для того, чтобы cygwin'ные программы работали
не только в внутри среды cygwin.

    gcc: какой он?

    Точно такой же, как и в UNIX. Сочный, мощный, безглючный. Однако, не
такой быстрый. Дело в том, что запуск препроцессора, компилятора, ассемблера и
линковщика требует определённого времени на загрузку и пролинковку в памяти
библиотеки cygwin1.dll, требумую каждым из этих компонентов gcc. Отмечу, что в
Windows 2000 это требует на порядок меньше времени, чем в Windows 98. Скорость
компиляции в Windows 2000 очень близка к скорости компиляции в UNIX. Но сок
остаётся соком: генерируемый бинарный код cygwin'ным gcc остаётся вне
конкуренции по компактности и эффективности!

    Если Вы когда-либо писали или компилировали программы под UNIX, Вы не
будете испытывать никаких трудностей в работе с cygwin. Только помните, что
cygwin'ный gcc может не поддерживать некоторые опции, которыми Вы пользуетесь
в UNIX'е, хотя количество таких недоразумений сведено к минимуму. На моём веку,
например, таких проблем не возникало. В любом случае, если возникают какие-то
проблемы, все мы дружно знаем лучший способ их решения: 'man gcc'! :)))

    Если же Вам не доводилось прежде заниматься программированием под UNIX
и Вы привыкли жать <F9> для того, чтобы скомпилировать Вашу программу,
расстраиваться не стоит. Попробуйте 'man gcc' в bash'е cygwin'а: вполне
достойное и увлекательное чтиво.

    Таки начнём?

    Оригинальничать я не буду, поэтому начнём мы, как всегда и везде, с
вывода 'hello world!' на консоль. Итак, hello.c:

#include <stdio.h>

int    main    ()    {

    printf("Hello World!\n");
    return 0;

}

    Компилируем:

    gcc -s hello.c -o hello.exe

    и смотрим на бинарник. 3072 байта бинарного кода, формат PE, portable
executable, загружаемые dll:

    cygwin1.dll, откуда hello.exe берёт нашу printf() и другие функции,
которые накомпилировал нам gcc;

    kernel32.dll, откуда hello.exe берёт GetModuleHandleA.

    Хидер <stdio.h> gcc берёт из /usr/include, который является дефолтной
инклудной директорией и в UNIX, и в cygwin'е.

    В cygwin'ном gcc есть одна очень приятная опция, которая, почему-то,
не задокументирована в man-файле, '-mno-cygwin'. Скомпилируем нашу программу
с этой опцией:

    gcc -mno-cygwin -s hello.c -o hello.exe

    и смотрим на бинарник: опять, 3072 байта бинарного кода, но наша
программа больше не нуждается в cygwin1.dll! вместо этого она использует
msvcrt.dll, где и находит нужную нам функцию printf.

    Если мы юзаем опцию '-mno-cygwin', cygwin кидает gcc'шный препроцессор
в директорию /usr/include/mingw, и, соответственно, gcc компилирует <stdio.h>
именно из этой директории.

    Настоятельно рекомендую совершить прогулку по содержимому директории
/usr/include для того, чтобы понять, что к чему. Думаю, Вас особо порадует
содержимое директорий /usr/include/sys и /usr/include/w32api.

    Таким образом, cygwin находит компромисс между двумя противоречащими
друг с другом платформами, UNIX и Windows и даёт нам уникальный шанс изучать
программирование под UNIX, не покидая Windows. Далее следует пример простенькой
программки, компилирующейся и под posix'овые BSD Sockets, и под WinSock2.
Программка открывает указанный в командной строчке порт и ожидает
tcp-соединение с любого IP-адреса, принимает от клиента литеру и возвращает
клиенту эту же литеру, увеличенную на единицу. Вы можете скомпилировать эту
программку, запустить её ('easy.exe 500'), приконнектиться к ней телнетом
('telnet 127.0.0.1 500') и ввести любой символ.

---[ Makefile (для неюниксоидов, Makefile с заглавной буквы 'M'):

# tiny makefile for a tiny program

all:
    @echo    Pick 'make posix' for UNIX/cygwin or 'make windows' for Windows

posix:
    @printf    "Building easy.c for posix..."
    @printf "#define ENV_POSIX" > plateform.h
    @gcc -s easy.c -o easy.exe
    @echo    ok!

windows:
    @printf "Building easy.c for windows..."
    @printf "#define ENV_WINDOWS" > plateform.h
    @gcc -mno-cygwin -s easy.c -lws2_32 -o easy.exe
    @echo    ok!

---[ easy.c:

#include "plateform.h"
#include <stdio.h>

#ifdef    ENV_POSIX
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>        // для INADDR_ANY
#include <signal.h>        // для signal()
#else
#include <winsock2.h>
#endif

int    main    (int argc, char **argv)    {

    struct    sockaddr_in    dst;
#ifdef    ENV_POSIX
    int    sock, sid;
#else
    SOCKET    sock, sid;
    WSADATA    wsaData;
#endif
    int             len = sizeof(struct sockaddr);
    char             buf;
    unsigned short        port;

// entry point

    if(argc<2)    {
        printf("Usage: easy.exe <tcp-port>\n");
        return 1;
    }

    port = atoi(argv[1]);

    if(!port)    {
        printf("Bad <tcp-port> defined!\n");
        return 2;
    }

#ifdef ENV_POSIX    // в позиксе мы игнорируем сигналы, мало ли :)
    signal(SIGPIPE, SIG_IGN);
#else ENV_WINDOWS    // в Windows мы проверяем версию винсока, мало ли :)
    printf("Testing if the WinSock2 version is equal or higher than 2.1...");
    if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0)    {
        printf("failed!\n");
        return 1;
    }
    printf("ok!\n");
    fflush(stdout);
#endif

    dst.sin_family = AF_INET;
    dst.sin_addr.s_addr = htonl(INADDR_ANY);
    dst.sin_port = htons(port);
    sock = socket(AF_INET,SOCK_STREAM,0);
    printf("Waiting for an incoming connection..."); fflush(stdout);
    bind(sock,(struct sockaddr*)&dst,len);
    listen(sock,1);
    sid = accept(sock,(struct sockaddr*)&dst,&len);
    printf("done!\nWaiting for incoming data..."); fflush(stdout);
    recv(sid,&buf,1,0);
    printf("received: [%2X]...",buf); fflush(stdout);
    buf++;
    send(sid,&buf,1,0);
    printf("done!\n");

#ifdef ENV_POSIX
    close(sock);
#else
    WSACleanup();
    closesocket(sock);
#endif

    return 0;
}

    Итак, мы набираем 'make posix' для того, чтобы собрать программу под
UNIX'ом или под cygwin'ную среду или 'make windows' для того, чтобы не зависеть
от cygwin'а и использовать лишь kernel32.dll, ws2_32.dll и msvcrt.dll, которые
входят в стандартную поставку каждого дистрибутива Windows. Обратите внимание
на размер бинарника: 4096 байт для cygwin, 4608 байт для windows! :)

    На этот раз всё! Ждите вскоре следующей статьи в ближайшее время:

    Технология сканирования сетей: Cокетный движок

Примеры небольших программ

страницы в данном разделе 
 Using Assembly Language in Linux.  "Разрешение монитора" выворачиваем на изнанку
 Активный сервер Web: расширения CGI  Скопировать файл построчно
 Побайтное копирование файла  HTML Encyclopaedia
 Первая программка  показывает данные принятые от GET запроса
 Выводит случайную картинку  Примеры небольших программ
 Записывает в файл Host, REMOTE_HOST, HTTP_USER_AGENT и выводит картинку  Программа, совмещающая команды mv и cp.
 POST запрос url decode  Выводит QUERY_STRING
 Показывает переменные окружения сервера  Показывает время на сервере
 Изменение размера файла  Surveys Online!
 URL DECODE  Перенаправляет в зависимости от юзер агента
 Показывает юзер агент и хост   


Разделы
Околокомпьютерная литература (375)
Программирование (102)
Программы (75)
ОС и Сети (49)
Интернет (29)
Аппаратное обеспечение (16)
Базы данных (6)

Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)

PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C





 
©  programming-lang.com  справочник программиста