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

Крок 3 – Отримання імені хоста

Створюємо проект, як і минулого разу, але з ім’ям Winsock2.

По-перше виносимо ініціалізацію і закриття Winsock в окремі процедури. Загальний код програми тепер виглядає ось так.

void StartWinsock();

void StopWinsock();

void WaitSocket();

void main()

{

StartWinsock();

WaitSocket();

StopWinsock();

}

Функція WaitSocket створена на перспективу, тобто потім будемо створювати сокет, що очікує. А поки у ній є тільки функція отримання імені хоста. Ось як вона виглядає:

void WaitSocket() {

char chInfo[64];

if (gethostname(chInfo, sizeof(chInfo)))

{

printf("Function gethostname...

Failed!\n");

return;

}

else

{

printf("Function gethostname...

Success!");

printf("\tHost name: \"%s\"\n",chInfo);

}

}

Головне у цьому коді – gethostname:

int gethostname (

char far * name,

int namelen

);

Ця функція повертає стандартне ім’я хоста для локальної машини. У неї передається буфер та його довжина для повертання імені. При відсутності помилок ця функція повертає 0.

Ось приклад роботи цієї програми

Startup Winsock... Success!

Function gethostname... Success! Host name: "MYCOMP"

Cleanup Winsock... Success!

Крок 4 – Створюємо сокет

Створюємо проект, як і минулого разу, але з ім’ям Winsock3.

Для поліпшення читання програми виносимо код для отримання і перевірки імені хоста в окрему процедуру.

void SocketGetHostName() {

char chInfo[64];

if (gethostname(chInfo, sizeof(chInfo)))

{

printf("Function gethostname...

Failed!\n");

return;

}

else

{

printf("Function gethostname...

Success!");

printf("\tHost name: \"%s\"\n",chInfo);

}

}

Вносимо зміни у WaitSocket для створення сокету.

void WaitSocket() {

SocketGetHostName();

SOCKET servsocket;

servsocket=socket(AF_INET, SOCK_STREAM, 0);

if (servsocket == INVALID_SOCKET)

{

printf("Creating socket... Failed!\n");

return;

}

else

printf("Creating socket... Success!\n");

if (closesocket(servsocket))

printf("Closing socket... Failed!\n");

else

printf("Closing socket... Success!\n");

}

Оголошуємо змінну servsocket типу SOCKET; ось як цей тип оголошений у “winsock.h

typedef u_int SOCKET;

Після чого викликаємо функцію socket, яка наш сокет і створює.

SOCKET socket(

int af, // сім’я адрес; у нашому

// випадку AF_INET

int type, // тип сокету:SOCK_STREAM або

// SOCK_DGRAM

int protocol // протокол, у нашому випадку

// 0 (TCP/IP)

);

Якщо вказано тип SOCK_STREAM то буде використовуватися TCP, а якщо SOCK_DGRAM, то UDP.

Протокол ми використовували за умовчанням, тобто TCP/IP. Результат повернення треба перевіряти на INVALID_SOCKET. Після роботи сокет необхідно обов’язково закривати .

Крок 5 – Зв’язок сокету з портом

Знов створюємо той же проект , що і в попередніх кроках.

Знову виносимо попередній код у процедури. Тільки змінну servsocket зробимо глобальною, так як вона буде використовуватися у багатьох командах. Те, що повинно знаходитись у цих процедурах, зрозуміло із попередніх кроків.

……………………

void CreateSocket();

void CloseSocket();

SOCKET servsocket;

……………………

Після створення сокету його треба зв’язати з конкретною адресою (номер порту теж входить в структуру адреси). Для цього існує функція bind. Але для зв’язку ще потрібен номер порту, тому оголошуємо його так:

#define PORT_ADDR 80

Ми намагаємося реалізувати сервер, який буде працювати за протоколом HTTP, а для цього протоколу за умовчанням використовується порт 80. Але взагалі можна використовувати будь-який інший порт.

Для організації зв’язку нам необхідно створити структуру SOCKADDR_IN. Вона необхідна для виконання команди bind; у ній знаходяться параметри зв’язку, такі як порт і атрибути. Ось її опис.

struct sockaddr_in{

short sin_family;

unsigned short sin_port;

struct in_addr sin_addr;

char sin_zero[8];

};

В даній структурі є вкладена структура sin_addr вона описана ось так:

struct in_addr {

union {

struct {unsigned char

s_b1, s_b2, s_b3, s_b4;}S_un_b;

struct {unsigned short s_w1, s_w2;} S_un_w;

unsigned long S_addr;

} S_un;

};

Після опису структур і їх заповнення даними можна викликати bind.

SOCKADDR_IN socketaddr;

socketaddr.sin_family = AF_INET;

socketaddr.sin_addr.s_addr = INADDR_ANY;

socketaddr.sin_port = PORT_ADDR;

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