Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Builder C++ изучаем вместе с автором.


<html>
<head>
<title>Xnomer</title>
<meta http-equiv="Содержимое-Тип" content="text/html; charset=windows-1251">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<div align="center">
  <table width="61%" border="1" cellspacing="1">
    <tr>
      <td>
        <div align="center">
          <p><a href="http://XNOMER.RU"><font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="5">X<i>NOMER.RU</i></font></b></font></a></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Написал
            недавно небольшое приложение &quot;клиент-сервер&quot;, смысл этого
            приложения заключается в передаче данных от клиента к серверу и обратно
            к клиенту. Изначально я сделал одно подключение, т. е. мы подключаемся
            к серверу и на этом подключения заканчиваются, но покопавшись в сокетах,
            было найдено множество полезной информации, например, ServerSocket
            может быть один, а ClientSocket-ов может быть множество, из чего следует,
            что подключения к сокетам сервера, может быть не малое количество.
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сегодня в этой рассылке я опишу только
            ключевые моменты этих исходных кодов, пример я выложу на сайт, который
            будет упакован в самораспаковывающийся архив. <br>
            На базе этих приложений, Вы сами сможете построить свое собственное
            приложение &quot;клиент-сервер&quot;. Напоминаю, что программируем
            мы на данный момент в C++ Builder 6.<br>
            Начнем мы с написания серверной части, я создал простую форму и расположил
            на ней 1 компонент, это ServerSocket с вкладки Internet. Активность
            этого компонента я сделал по умолчанию false, порт указал 1024 (прошу
            взять на заметку, порты должны быть одинаковые, что у клиента, что
            у сервера, через эти порты приложения будут взаимодействовать). Host
            я задал 192.168.0.1, так как у меня дома локальная сеть, то именно
            такой IP адрес на моем компьютере, но если у вас нет локальной сети,
            то по умолчанию у вас стоит 127.0.0.1. Чуть не забыл еще один компонент,
            это Label его тоже можно поставить, в нем мы напишем, что соединение
            прошло успешно.<br>
            Дальше будем описывать чисто код, так как серверу, по большому счету,
            больше и не нужно.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Изначально
            мы объявим две глобальные переменные:</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>int
            XX; <i><font color="#006600">// промежуточная переменная </font></i><br>
            String IntX; <i><font color="#006600">//сюда мы будем получать данные
            от клиента</font></i></b></font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Эти
            переменные не обязательно должны быть глобальными.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">При
            вызове формы, нам нужно сделать сервер активным:</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>__fastcall
            TForm1::TForm1(TComponent* Owner)<br>
            : TForm(Owner)<br>
            {<br>
            ServerSocket1-&gt;Active = true;<br>
            }</b></font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Как
            только мы делаем его активным, то сервер начинает слушать порт, который
            мы указали (1024)</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Далее
            в компоненте ServerSocket мы опишем событие OnAccept </font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>Label1-&gt;Caption
            = &quot;Подключение установлено&quot;; </b></font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Это
            событие сработает только тогда, когда клиент подключится к серверу.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Теперь
            перейдем к событию OnClientRead:</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>IntX
            = Socket-&gt;ReceiveText(); <i><font color="#006600">// сюда мы получаем
            данные от клиента</font></i><br>
            XX = 5 + StrToInt(IntX); <i><font color="#006600">// тут мы прибавим
            5 к переменной IntX </font></i><br>
            for (int i = 0; ServerSocket1-&gt;Socket-&gt;ActiveConnections &gt;
            i; i++)<br>
            {<br>
            ServerSocket1-&gt;Socket-&gt;Connections[i]-&gt;SendText(IntToStr(XX));
            <i> <font color="#006600">//посылаем данные обратно</font></i><br>
            } </b></font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Здесь на самом деле и есть ключевые
            моменты сервера, т. е. сначала мы получаем данные, что-то с ними делаем
            и отправляем их обратно.<br>
            Что конкретно мы делаем:<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. Записываем в IntX данные, которые
            нам прислал клиент.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. Сначала мы конвертируем переменную
            IntX в тип int, т. е. она у нас до конвертации была типом String(строкового
            значения), но что бы нам прибавить к IntX какую-то сумму то мы должны
            ее конвертировать в тип int, делается это так, StrToInt(IntX), дословно
            переведу, что бы было понятнее (СтрокуПереведемВчисло(IntX)), можно
            и на оборот, например, так: IntToStr(IntX), это переводится как (ЧислоПереведемВстроку(IntX)).
            В последнем случае это для наглядности, мы будем делать тоже самое,
            только с переменной XX. Далее мы прибавляем к IntX, число 5 и присваиваем
            результат промежуточной переменной XX. Зачем нам нужна промежуточная
            переменная спросите вы? Она нужна для того, что бы не было путаницы,
            точнее переменная IntX у нас объявлена как строка, поэтому конвертацию
            мы делаем только тогда, когда нам нужно сложить какое-то выражение,
            хотя тут можно и поэкспериментировать. <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. Теперь мы возьмем данные, которые
            хранятся в переменной XX и отправим их обратно клиенту. <br>
            Тут я организовал цикл. Этот цикл назначает соединение, т. е. в данном
            примере если подключен один клиент к серверу то Connections[i] будет
            равен &quot;0&quot;, если подключится второй клиент, то Connections[i]
            будет равен &quot;1&quot; и т. д. Я организовал этот цикл для того,
            чтобы можно было создавать условия для разных подключений, т. е. если
            мы опишем например такое условие в цикле if (i == 3) { посылаем этому
            клиенту что-то другое } то именно 4-тому по счету подключению, мы
            можем слать совсем другие данные. Почему 4-тому? Потому что отсчет
            начинается с &quot;нуля&quot;, значит Connections[3] - это соответственно
            4-тый подключенный клиент.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Все, на этом этапе мы закончили с сервером,
            можете откомпилировать проект.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Переходим
            к клиенту.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Наш
            клиент будет подключаться непосредственно к серверу и указанному порту
            (1024).<br>
            Создаем новый проект и размещаем на нем такие компоненты:<br>
            ClientSocket, Button1, Button2, Edit, Image.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Теперь разберем по порядку все компоненты,
            которые мы установили на форму, и настроем некоторые из них:<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. ClientSocket нужен нам для подключения
            к серверу. Active сделаем false, далее нам нужно будет добавить одно
            событие в этот компонент, но мы это сделаем позже, когда вернемся
            к ключевым моментам клиента. <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. Button1 нам нужен для соединения
            с сервером.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. Button2 нам будет нужен для посылки
            данных.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. Поле Edit, в нем мы напишем IP адрес
            сервера.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5. И Image, нам понадобится для того,
            что бы видеть результат нашей работы.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Я выбрал простой способ отправки данных
            и передачи их определенному компоненту, т. е. в данном случае, все
            это может показаться бесполезным, но если поразмыслить над этим, то
            можно создать вполне полезное приложение которое будет исполнять необходимые
            функции. </font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Приступим
            к написанию кода:<br>
            Объявим глобальную переменную:<br>
            String server1;</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Эта
            переменная будет хранить адрес сервера, т. е. ее мы будем использовать
            для IP адреса, который напишем в компоненте Edit.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Теперь
            опишем событие, которое будет вызываться при нажатии одной из кнопок
            (Button1) я дал этой кнопке название &quot;Соединение&quot;.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>if
            (ClientSocket1-&gt;Active) <i><font color="#006600">//проверка на
            активность</font></i><br>
            ClientSocket1-&gt;Active = false;<br>
            server1 = Edit1-&gt;Text; <font color="#006600"><i>// вносим в переменную
            адрес</i></font><br>
            if (server1.Length() &gt; 0) <font color="#006600"><i>// проверка
            наличие значения в переменной</i></font><br>
            { <br></b></font><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>ClientSocket1-&gt;Host
            = server1; <br>
            ClientSocket1-&gt;Active = true; <font color="#006600"><i>//включаем</i>
            </font><br>
            }</b></font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Разберем
            условия, которые должны выполниться:<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. Идет проверка на активность ClientSocket1
            если ClientSocket1-&gt;Active то мы его выключаем (false).<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. Дальше мы берем из компонента Edit1
            IP адрес сервера в переменную server1.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. Теперь мы проверяем условие на наличие
            значения в переменной server1. Если значение есть, то берем это значение
            в ClientSocket1-&gt;Host т. е. назначаем IP адрес сервера. Вы должны
            понимать, что и порт мы тоже можем указать таким образом. Мы, конечно,
            могли указать адрес явно в самом компоненте, но я решил усложнить
            задачу, только лишь для того, что бы было понятно, что мы можем управлять
            и настраивать компоненты не внутри программы, а уже в откомпилированной.
            Нужно лишь создать такие условия. <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. Запускаем компонент в работу ClientSocket1-&gt;Active
            = true.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Теперь
            рассмотрим вторую кнопку, у которой будет простое событие отправки
            данных. Я назвал эту кнопку &quot;Перемещение&quot;.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>int
            koord;<br>
            koord = Image1-&gt;Left;<br>
            ClientSocket1-&gt;Socket-&gt;SendText(IntToStr(koord))</b>;</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Мы
            объявили переменную koord, она будет содержать левую координату компонента
            Image1, т. е. у этого компонента имеются две координаты как X и Y,
            отсчет идет с левого верхнего угла, если мы разместим картинку в самом
            верхнем левом углу формы, то мы получим такие координаты 0 и 0. Кстати,
            не забудьте загрузить картинку в этот компонент, через метод Picture,
            я туда загрузил простой BMP файл. Теперь, когда мы загрузили число
            в переменную, нам нужно ее отправить на сервер. Естественно ясли мы
            не соединены с сервером, то данные ни куда не уйдут. Перед этой процедурой,
            нам нужно нажать кнопочку &quot;Соединение&quot;, и только тогда нажать
            кнопку &quot;Перемещение&quot;. Ну, если даже, вы все сделали правильно,
            и соединение прошло успешно (о чем нам будет говорить label1 установленный
            на сервере), то все равно никакого действия не произойдет, а скорее
            всего возникнет ошибка. Эта может быть только в том случае, когда
            данные пытаются вернуться обратно, но у нас на данном этапе событие
            приема сообщения от сервера отсутствует. Что мы сейчас и сделаем,
            вернемся к нашему компоненту ClientSocket1 и пропишем ему в событие
            OnRead, вот такую строчку:</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>Image1-&gt;Left
            = StrToInt(Socket-&gt;ReceiveText())</b></font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вот
            в принципе и весь фокус такой простой схемы как отправка, обработка,
            возвращение данных через WinSocket. Если вы запустите одновременно
            и сервер и клиент, пусть даже на одном компьютере, правильно пропишите
            сетевой адрес, подключитесь к серверу и нажмете кнопку &quot;Перемещение&quot;,
            то вы должны увидеть весь результат этого действия наглядно. Пример
            приложения клиент- сервер можно скачать с сайта.</font> </p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><a href="http://xnomer.ru/vipuski.php">Cкачать
            пример с сайта</a>. Написать письмо можно на этот ящик <a href="mailto:pochta@xnomer.ru%20">pochta@xnomer.ru</a>
            или оставить пожелания в <a href="http://xnomer.ru/kniga/go.php">гостевой
            книге</a> на сайте. Мне очень важно ваше мнение.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">С
            Уважением Дмитрий!.</font></p>
          <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Удачи!</font></p>
        </div>
      </td>
    </tr>
  </table>
</div>
</body>
</html>


В избранное