Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
[MIT] / 14 steps.doc
Скачиваний:
17
Добавлен:
07.02.2016
Размер:
181.25 Кб
Скачать

Void chttpServerView::OnLButtonDown(uint nFlags, cPoint point)

{

// TODO: Add your message handler code here and/or call default

if (!blTestStartServer)

{

if (HTTPServer.StartServer(m_hWnd))

{

CHTTPServerDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

pDoc->csInfo="Server Start";

Invalidate();

blTestStartServer=TRUE;

}

}

CView::OnLButtonDown(nFlags, point);

}

void CHTTPServerView::OnRButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

if (blTestStartServer)

{

HTTPServer.StopServer();

CHTTPServerDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

pDoc->csInfo="Server Stop";

Invalidate();

blTestStartServer=FALSE;

}

CView::OnRButtonDown(nFlags, point);

}

Коли до сервера звернеться клієнт, буде згенеровано повідомлення WM_SERVER_ACCEPT, обробкою якого ми і займемося. Для цього додамо один рядок у блок обробки повідомлень

BEGIN_MESSAGE_MAP(CHTTPServerView, CView)

//{{AFX_MSG_MAP(CHTTPServerView)

ON_WM_LBUTTONDOWN()

ON_WM_CANCELMODE()

ON_WM_RBUTTONDOWN()

//}}AFX_MSG_MAP

ON_MESSAGE(WM_SERVER_ACCEPT, OnServerAccept)

END_MESSAGE_MAP()

і також функцію-обробник

afx_msg LRESULT CHTTPServerView::OnServerAccept(WPARAM wParam, LPARAM lParam)

{

CHTTPServerDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

pDoc->csInfo="Client Connected !";

Invalidate();

return 0L;

}

Треба усунути одну помилку, яку ми допустили на п’ятому (фактично – четвертому) кроці при вказуванні порту в BindSocket. Це відсутність функції перетворення порядку байтів хоста в порядок байтів TCP/IP.

socketaddr.sin_port = htons(PORT_ADDR);

А тепер можна й протестувати. Компілюємо і запускаємо програму, лівої кнопкою стартуємо сервер, відкриваємо Internet Explorer або інший браузер і вводимо до його рядка адресу http://localhost; якщо обрано інший порт, то адреса буде вигледіти так: http://localhost:порт, тобто після назви хоста через двокрапку вказується номер порту у десятковому вигляді (наприклад http://localhost:8080).

Якщо ви програмуєте під Windows 2000 і заходили у систему не з правами адміністратора, то ви не зможете використовувати порти з номером менше 1024, так як вони зарезервовані для системних програм.

Якщо все гаразд, то у вікні програми з’явиться надпис “Client connected”. Але у браузері нічого не з’явиться бо нічого не відсилаємо браузеру на його запит. Як відсилати дані ми розглянемо у наступному кроці.

Крок 9 – Відсилаємо документ

Проект залишаємо той же, потрібно внести зміни лише в одну функцію – OnServerAccept.

afx_msg LRESULT

CHTTPServerView::OnServerAccept

(WPARAM wParam, LPARAM lParam)

{

CHTTPServerDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

pDoc->csInfo="Client Connect !";

Invalidate();

If (wsagetasyncerror(lParam))

{

AfxMessageBox("Error detecting client");

return 0L;

}

if (WSAGETSELECTEVENT(lParam) == FD_ACCEPT)

{

int length=sizeof(SOCKADDR);

SOCKADDR_IN socketclientaddr;

HTTPServer.clientsocket=accept(HTTPServer.servsocket, (LPSOCKADDR) &socketclientaddr, (LPINT) &length);

if (HTTPServer.clientsocket == INVALID_SOCKET)

{

AfxMessageBox("Invalid Client Socket");

return 0L;

}

CString buff="HTTP/1.0 200 OK\n\n\

<HTML>\

<TITLE> Simple HTTP Server</TITLE>\

<BODY>\

<P>\

<FONT size=\"7\">Our Server Working Perfectly!!!\

</BODY>\

</HTML>";

HTTPServer.SendData(buff, buff.GetLength());

closesocket(HTTPServer.clientsocket);

}

return 0L;

};

До цієї функції-обробника передаються параметри SOCKET у wParam (у нашому випадку так як сокет один, то ми їм не користуємося, але якщо б було декілька сокетів, то єдиний спосіб дізнатися, від якого сокету надійшло повідомлення, це wParam) і код події у lParam (у нашому випадку нам повинно приходити лише FD_ACCEPT, але на всяк випадок перевіряємо). Якщо усе гаразд, то викликаємо accept для створення сокету клієнта (він створюється шляхом копіювання сокету вказаного у параметрі цієї функції, і після копіювання сокет з якого ми копіювали знов переводиться у стан чекання). Тепер можна надсилати дані. Посилку даних виносимо до окремої функції.

Соседние файлы в папке [MIT]