Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 8 мая!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Программисты долго мучаются с кодом прогаммы, изучают С++, WinAPI функции, MSDN. Потом пишут банальную систему защиты или навешивают банальный протектор, а крэкеры и реверсеры справляются с такой защитой за 5 минут. В итоге, продажи программы почти нулевые. Чтобы такого не допустить, тут самому надо немного поднабрать опыта отладки, реверсинга, тот же отладчик Ollydbg изучить или дизассемблер IDA Pro. Но где искать по крохам эти знания? Нет, конечно можно годами "методом тыка" разбираться, но куда быстрее видеокурс специальный посмотреть. Вот тут он есть: ссылка. Автор курса с большим опытом и объясняет понятно, я из этого курса много узнал про то как работает компьютер, процессор, про инструменты специальные и как с ними работать. Мои коллеги программисты на работе ничего такого и не знают, теперь я им нос утру.

Visual C++. MFC
Урок 34. Пишем сервер с использованием CSocket

Приступаем непосредственно к созданию сетевого приложения. Работать оно сможет как в пределах одного, так и двух компьютеров. Соединение между клиентской и серверной частями будет происходить по протоколу TCP/IP. Если у вас только один компьютер, то в качестве адреса сервера клиент должен будет указать адрес 127.0.0.1. Этот адрес всегда показывает на ваш компьютер, что очень удобно при отладке сетевых прилжений.

На этом занятии мы напишем серверную часть нашего приложения. Запустите мастер MFC AppWizard и создайте с его помощью основанное на диалоге приложение. В качестве имени проекта наберите server. На шаге 2 обязательно поставьте галочку для поддержки Windows Sockets:

Шаг 2

На этом же шаге можно убрать галочки для окошка About и для поддержки ActiveX'ов.

После создания заготовки для нашей программы разместите на форме одну кнопку (с идентификатором IDC_LISTEN и заголовком Listen) и один edit (с идентификатором IDC_DATA). При нажатии на кнопку Listen сервет начнет слушать сеть. После того, как клиент подсоединится к нашему серверу и отправит некоторые данные, они появятся в нашем edit'е. Для простоты после соединения только клиент сможет отправлять данные. Если вы захотите отправлять даные и с сервера, то вам придется добавить в серверную часть нашей программы код, аналогичный коду клиентской части (которую мы рассмотрим на следующем уроке).

После размещения всех элементов наша программа будет выглядеть приблизительно так:

Серверная часть

К нашему edit'у (с идентификатором IDC_DATA) припишите с помощью ClassWizard'а переменную m_sData типа CString.

Приступаем непосредственно к написанию кода.

Создаем новый класс CMySocket как потомок класса CSocket:

Создание нового класса

Добавляем в него переменную типа указатель на CServerDlg:

public:
 
     CServerDlg* m_pDlg;

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

class CServerDlg;

непосредственно перед объявлением класса CMySocket.

Далее мы должны добавть метод для задания переменной m_pDlg. Назовите его SetParentDlg. Реализация для него самая простая

void CMySocket::SetParentDlg(CServerDlg *pDlg)
 
 {
 
     m_pDlg=pDlg; //Указатель на диалоговое окно
 
 }

Теперь нам надо в нашем классе написать 2 виртуальные функции - OnAccept и OnReceive. Первая будет вызываться, когда наш слушающий сеть сокет получит запрос на соединение с клиентской стороны. Вторая - при получении данных от клиента. Для добавления виртуальной функции OnAccept щелкните на вкладке ClassView на классе CMySocket правой кнопкой мыши и выберите Add Virtual Function. В появившемся окне New Virtual Override for Class CMySocket двойным щелчком перенесите функции OnAccept и OnReceive в правый listbox и нажмите на OK.

Добавление виртуальных функций

В созданные заготовки для функций добавьте следующий код:

void CMySocket::OnAccept(int nErrorCode)
 
 {
 
     // TODO: Add your specialized code here and/or call the base class
 
     AfxMessageBox("Соединение");
 
     m_pDlg->OnAccept();
 
     CSocket::OnAccept(nErrorCode);
 
 }
void CMySocket::OnReceive(int nErrorCode)
 
 {
 
     // TODO: Add your specialized code here and/or call the base class
 
     AfxMessageBox("Данные получены");
 
     m_pDlg->OnReceive();
 
     CSocket::OnReceive(nErrorCode);
 
 }

В этих двух фрагментах мы после показа MessageBox'а (для наглядности процесса) вызываем одноименные функции нашего диалогового окна (через переменную m_pDlg, которая как раз и будет хранить указатель на главное окно). Эти функции диалогового окна у нас пока не написаны. Почему код по обработке лучше присать в классе диалогового окна, а не в классе сокета? Так как данные, в общем-то, пересылаются именно диалоговому окну, а не нашему сокету. Вот пусть диалоговое окно и разбирается. Но, в принципе, всю обработку можно было делать и в классе сокета. Так как мы в этом фрагменте используем переменную m_pDlg, то перед реализацией методов пишем строку

...
 
 #include "ServerDlg.h"
 
 ...

Теперь займемся классом диалогового окна. Для начала задайте в нем две переменные типа CMySocket:

...
 
 #include "MySocket.h"
 
 ...
 
 class CServerDlg : public CDialog
 
 {
 
 public:
 
     CMySocket m_pListenSocket; //Слушающий сокет
 
     CMySocket m_pConnectSocket; //Передающий сокет
 
     ...

Обратите внимание на добавленый include - без него компилятор будет ругаться на строчки с двумя добавленными сокетами.

Как вы видите, сокетов у нас два. Первый (m_pListenSocket) - слушающий сокет. Когда серверная часть нашего приложения начинает работать, именно он слушает на определенном порту, не захочет ли какой-нибудь клиент подсоединится. Как только от клиента поступит запрос на подсоединение, то наш слушающий сокет m_pListenSocket переведет соединение на передающий сокет m_pConnectSocket, а сам будет продолжать слушать дальше (код по переводу соединения мы еще напишем). А передачей данных будет заниматься наш второй сокет - m_pConnectSocket.

Пишем код дальше. В методе OnInitDialog зададим значение для переменой m_pDlg сокетов (вызовом метода SetParentDlg):

BOOL CServerDlg::OnInitDialog()
 
 {
 
     ...
 
     // TODO: Add extra initialization here
 
     m_pListenSocket.SetParentDlg(this);
 
     m_pConnectSocket.SetParentDlg(this);
 
     m_pListenSocket.Create(2000); //Создаем сокет на 2000 порту
 
     return TRUE;  // return TRUE  unless you set the focus to a control
 
 }

Таким образом переменная m_pDlg будет показывать на текущее диалоговое окно.

Далее пишем методы OnAccept и OnReceive:

void CServerDlg::OnAccept()
 
 {
 
     //Переводим соединение на передающий сокет
 
     m_pListenSocket.Accept(m_pConnectSocket);
 
 }
 
 
 
 void CServerDlg::OnReceive()
 
 {
 
     char *pBuf=new char[1025];
 
     //Записываем полученные данные в pBuf
 
     //Записываем в n количество полученных байтов
 
     int n=m_pConnectSocket.Receive(pBuf, 1024);
 
     //Отсекаем лишние символы
 
     pBuf[n]=NULL;
 
     //Записываем данные в переменную, связанную с edit'ом
 
     m_sData=pBuf;
 
     UpdateData(FALSE);
 
 }

Теперь осталось написать код для кнопки Listen. Именно по нажатию на эту кнопку сокет m_pListenSocket начинает слушать сеть. Создайте обработчик для этой кнопки и добавьте в него следующий код:

void CServerDlg::OnListen()
 
 {
 
     // TODO: Add your control notification handler code here
 
     m_pListenSocket.Listen(); //Сокет начинает слушать
 
 }

С написанием сервера все! На следующем уроке мы напишем клиента.



<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS