
- •Крок 1 – Що такеWindows Sockets
- •Крок 2 – Ініціалізація
- •Крок 3 – Отримання імені хоста
- •If (bind(servsocket, (lpsockaddr)
- •Int bind(
- •Int namelen
- •Крок 6 – Зв’язок вікна з сокетом для отримання повідомлень
- •Назву вікна визначимо як
- •Void BindSocket();
- •Int listen (
- •Void StopServer();
- •If (!cDocument::OnNewDocument())
- •Void chttpServerView::OnDraw(cdc* pDc)
- •Void chttpServerView::OnLButtonDown(uint nFlags, cPoint point)
- •Invalidate();
- •Крок 9 – Відсилаємо документ
- •Invalidate();
- •If (wsagetasyncerror(lParam))
- •Void cServerWinsock::SendData(lpctstr buf, int len)
- •If accept() send()
- •Крок 10 – Порядок байтів
- •Коли Ви повинні перетворювати порядок байтів
- •Коли Вам не потрібно перетворювати порядок байтів
- •Функції перетворення порядку байтів у Windows Sockets
- •If (bind(servsocket, (lpsockaddr) &socketaddr, sizeof(socketaddr)))
- •Розрив зв’язку
- •Крок 12 – Робимо файл звіту
- •Void chttpServerView::OnToolsOptions()
- •Void chttpServerView::OnToolsOptions()
- •Void cServerWinsock::LogWrite(cString csStr)
- •If (wsaStartup(winsock_version, &wsaData))
- •Invalidate();
- •Функції адрес
- •Функції розширення Microsoft Winsock
If (bind(servsocket, (lpsockaddr)
&socketaddr, sizeof(socketaddr)))
{
printf("Binding socket... Failed!\n");
}
else
printf("Binding socket... Success!\n");
Функція bind
Int bind(
SOCKET s,
const struct sockaddr FAR* name,
Int namelen
);
Якщо усе нормально, то дана функція поверне 0, інакше –SOCKET_ERROR.
Крок 6 – Зв’язок вікна з сокетом для отримання повідомлень
Робимо ще один проект.
При роботі сервера йому будуть відсилатися повідомлення. Для їх отримання необхідно вказати, куди вони підуть. Це робиться функцією WSAAsyncSelect. Тільки тут є одна проблема. У цієї функції є один параметр HWND – ідентифікатор вікна. Для консольної програми прямим методом його отримати не можна. Коли ми далі перейдемо на MFC, цей параметр буде повертатись операційною системою (коли ми створюємо вікно, як результат виконання функції CreateWindow повертається HWND). Тому знаходити HWND будемо використовуючи функцію Win32 API з ім’ям FindWindow, яка по імені вікна повертає його HWND.
Так як ця функція знаходиться у USER32.DLL для того, щоб нею скористатися нам потрібна USER32.LIB, тому потрібно її підключити.
Для того, щоб скористатися ім’ям вікна, його потрібно знати, а так як вікно створюємо не ми, то ми не можемо знати напевно як воно називається. Тому ми самі дамо назву вікну за допомогою функції SetConsoleTitle, яка дозволяє встановити назву консольного вікна.
Назву вікна визначимо як
#define NAME_SERVER_SOCKET “This is HTTP server version 1.0”
HWND GetConsoleHWND()
{
SetConsoleTitle(NAME_SERVER_SOCKET);
HWND hwndConsoleWindow;
hwndConsoleWindow=FindWindow(NULL,
NAME_SERVER_SOCKET);
if (hwndConsoleWindow==0)
{
printf("Error Find Window");
return NULL;
}
return hwndConsoleWindow;
}
У цьому фрагменті коду ми встановлюємо назву вікна (SetConsoleTitle), а потім шукаємо вікно з такою назвою (FindWindow).
Як завжди виносимо попередній крок в окрему функцію.
Void BindSocket();
Крім того, якщо вікно з результатами роботи програми дуже швидко зникає, то у кінці коду можна додати виклик функції Sleep, яка зупиняє подальшу роботу програми на вказану кількість міллісекунд.
void main()
{
StartWinsock();
WaitSocket();
StopWinsock();
Sleep(1000);
}
Приведемо тепер код функції WaitSocket
void WaitSocket()
{
SocketGetHostName();
CreateSocket();
BindSocket();
int Errors;
Errors = WSAAsyncSelect(servsocket,
GetConsoleHWND(),
WM_SERVER_ACCEPT, FD_ACCEPT);
if (Errors == SOCKET_ERROR)
{
printf(“WSAAsyncSelect… Failed!\n”);
return;
}
else printf(“WSAAsyncSelect… Success!\n”);
CloseSocket();
}
Функція WSAAsyncSelect вимагає, щоб повідомлення wMsg було надіслано до вікна hWnd, якщо у сокеті s виникає подія lEvent.
int WSAAsyncSelect (
SOCKET s,
HWND hWnd,
unsigned int wMsg,
long lEvent
);
Параметр wMsg вказує, яке повідомлення буде відсилатися. Опишемо його як
const int WM_SERVER_ACCEPT = WM_USER + 1;
У параметрі lEvent ми передаємо FD_ACCEPT, який говорить, що треба відсилати повідомлення при спробі підключення до сокету.
При вдалому виконанні функції повертається 0, інакше –SOCKET_ERROR.
Крок 7 – Сокет, що очікує
Виносимо минулий крок у окрему функцію.
……………..
void LinkWindowSocket();
……………..
Після усіх налагоджень є можливість встановити сокет у стан чекання. Це робиться командою listen. Приведемо код.
void WaitSocket()
{
SocketGetHostName();
CreateSocket();
BindSocket();
LinkWindowSocket();
int Errors;
Errors = listen(servsocket, QUEUE_SIZE);
if (Errors == SOCKET_ERROR) {
printf(“Listening… Failed!\n”);
return;
}
else printf(“Listening… Success!\n\tWaiting
connection… \n”);
CloseSocket();
}
Деяка специфіка програм Win32 Console не дає можливості отримувати повідомлення Windows. Але якщо би ми програмували зразу на MFC, то цього було би вже досить, щоб одразу перейти до обробки повідомлення. А поки ми лише бачимо, що усе гаразд і програма завершує роботу.
Так, функція listen переводить сокет у режим чекання.