Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab_m1 / lab_m1.doc
Скачиваний:
67
Добавлен:
07.02.2016
Размер:
2.69 Mб
Скачать

4.7.2 Створення й видалення сокета

Функція створення сокета має такий вигляд:

SOCKET socket(int af, int type, int protocol),

де af - характеризує набір протоколів, у рамках якого будуть взаємодіяти клієнт і сервер (це може бути TCP/IP, UDP, IPX і т.д.). Для протоколу TCP/IP параметр af повинен бути дорівнює AFINET, що відповідає формату адреси, прийнятому в Internet. type - визначає тип комунікацій (SOCKSTREAM, і SOCKDGRAM). Якщо даний параметр дорівнює SOCKSTREAM, то сокет буде використаний для передачі даних через канал зв'язку з використанням протоколу TCP/IP. Якщо ж використовується SOCKDGRAM, то передача даних буде виконуватися без створення каналів зв'язку через датаграмний протокол UDP,

protocol - задає код конкретного протоколу із зазначеного набору (заданого af), що буде реалізований у даному з'єднанні. Протоколи позначаються символьними константами із префіксом IPPROTO_ (наприклад, IPPROTOIP або IPPROTOUDP). Допускається значення protocol=0 (протокол не зазначений), у цьому випадку використовується значення за замовчуванням для даного виду з'єднань.

Параметр, що повертається, являє собою дескриптор з'єднувача.

Якщо операція socket завершилася успішно, вихідний параметр дорівнює дескриптору з'єднувача, у іншому випадку - INVALIDSOCKET (-1). За допомогою оператора WSAGetLastError можна одержати код помилки, що проясняє причину негативного результату.

Знищує сокет функція:

closesocket(SOCKET s)

де s - змінна типу TSocket, отримана в результаті виклику функції Socket.

Приклад створення сокета:

Var

MySokcet : Tsocket;

begin

MySocket := socket(AF_INET, SOCKSTREAM, IPPROTOIP);

If (MySocket = INVALIDSOCKET)

Then ShowMessage('Сокет не створений')

Else

// Ваші подальші дії

End.

4.7.3 Прив'язка адреси до сокету

Функція зв'язування сокета з фізичною адресою має вигляд:

int bind(SOCKET s, const struct socketaddr FAR* name, int namelen)

де s - цілочислений код дескриптора;

name - містить три величини: IP-адреса, код протокольного набору, номер порту, що визначає характер додатка; namlen - визначає довжину другого параметра. Структура адресної інформації має вигляд:

struct sockaddr_in{

short sinfamily; {Вказується протокол}

unsigned short sin_port; {Вказується порт}

struct inaddr sinaddr; {Вказується IP-адреса}

char sin_zero[8]

};

У серверній частині додатка IP-адреса можна зробити рівним INADDRANY (або =0), тому що серверу не обов'язково знати свою IP-адреса. При коректному виконанні функція bind повертає код 0, у противному випадку SOCKET_ERROR=-1.

Приклад:

Var

MySockAddr : TsockAddrIn; ErrBind : integer; begin

MySockAddr.sinfamily := AFINET; MySockAddr.sin_port := htons(1024); MySockAddr.sin_addr.s_addr := INADDRANY; ErrBind := bind(MySock, MySockAddr, SizeOf(MySockAddr));

If (ErrBind <> 0) then

ShowMessage('Помилка зв'язування адреси із сокетом')

Else

// Ваші подальші дії

end.

4.7.4 Очікування й обробка запитів на підключення клієнта

Для того, щоб сокет очікував підключення, його необхідно перевести в стан, що очікує, за допомогою функції listen:

int listen(SOCKET s, int backlog);

де backlog - задає максимальний розмір черги для запитів з'єднання, що приходять, тобто скільки запитів може бути прийняте на обслуговування без втрат. Сокет, що очікує, посилає кожному відправникові повідомлення-відгук, що підтверджує одержання запиту на з'єднання.

Запити із черги, сформованою функцією listen, обробляються функцією accept, що встановлює зв'язок із сокетом клієнтів:

int accept(SOCKET s, struct sockaddr FAR*addr, int FAR*addrlen);

де s - дескриптор з'єднувача, що прослуховує з'єднання (той же, що й в listen);

addr - покажчик на структуру, що містить адресу; addrlen - покажчик на довжину адреси addr.

При виникненні помилки вертається код INVALIDSOCKET.

Приведемо приклад використання функцій linsten і accept:

Var

AcceptSocket : Tsocket; AcceptAddr : ASockAddr_In; SizeAcceptAddr : AInteger; ErrListen : integer;

Begin

ErrListen := listen(MySock, 5);

If (ErrListen <> 0) then ShowMessage('Черга для запитів не сформована');

Else Begin

AcceptSocket := accept(MySock, @AcceptAddr, @SizeAcceptAddr);

If (AcceptSocket = INVALIDSOCKET) then ShowMessage('Клієнт не приєднався')

else

// Ваші подальші дії

End;

End.