- •Практичне заняття 10
- •Сокети (sockets) в unix і основи роботи з ними.
- •Системні виклики sendto() і recvfrom()
- •Визначення ip-адрес для обчислювального комплексу
- •Приклад програми udp-клієнта
- •Приклад програми udp-серверу
- •Організація зв'язку між процесами за допомогою установки логічного з'єднання
- •Встановлення логічного з'єднання. Системний виклик connect()
- •Приклад програми tcp-клієнта
- •Як відбувається встановлення віртуального з'єднання
- •Системний виклик listen()
- •Системний виклик accept()
- •Приклад простого tcp-серверу
- •Вживання інтерфейсу мережних викликів для інших сімейств протоколів. Unix Domain протоколи. Файли типу "сокет"
Визначення ip-адрес для обчислювального комплексу
Для визначення IP-адрес на комп'ютері можна скористатися утилітою /sbin/ifconfig. Ця утиліта видає всю інформацію про мережні інтерфейси, конфігуровані в обчислювальній системі. Приклад видачі утиліти показаний нижче:
eth0 Link encap:Ethernet HWaddr 00:90:27:A7:1B:FE
inet addr:192.168.253.12 Bcast:192.168.253.255
Mask:255.255.255.0
BROADCAST NOTRAILERS RUNNING MULTICAST MTU:1500
Metric:1 RX расkets:122556059 errors:0 dropped:0
overruns:0 frame:0 TX расkets:116085111 errors:0
dropped:0 overruns:0 carrier:0 collisions:0
txqueuelen:100 RX bytes:2240402748 (2136.6 Mb)
TX bytes:3057496950 (2915.8 Mb) Interrupt:10
Base address:0x1000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
LOOPBACK RUNNING MTU:16436 Metric:1
RX расkets:403 errors:0 dropped:0 overruns:0 frame:0
TX расkets:403 errors:0 dropped:0 overruns:0
carrier:0 collisions:0 txqueuelen:0
RX bytes:39932 (38.9 Kb) TX bytes:39932 (38.9 Kb)
Приклад 15-16.0. Інформація про мережні інтерфейси.
Мережний інтерфейс eth0 використовує протокол Ethernet. Фізична 48-бітова адреса, зашита в мережній карті, – 00:90:27:A7:1B:FE. Його IP-адреса – 192.168.253.12.
Мережний інтерфейс lo не відноситься ні до якої мережної карти. Це так званий локальний інтерфейс, який через загальну пам'ять емулює роботу мережної карти для взаємодії процесів, що знаходяться на одній машині за повними мережними адресами. Наявність цього інтерфейсу дозволяє відладжувати мережні програми на машинах, що не мають мережних карт. Його IP-адреса звичайно однакова на всіх комп'ютерах – 127.0.0.1.
Приклад програми udp-клієнта
Розглянемо, нарешті, простий приклад програми 15–16-1.с. Ця програма є UDP-клієнтом для стандартного системного сервісу echo. Стандартний сервіс приймає від клієнта текстову датаграму і, не змінюючи її, відправляє назад. За сервісом зарезервований номер порту 7. Для правильного запуску програми необхідно вказати символьну IP-адресу мережного інтерфейсу комп'ютера, до сервісу якого потрібно звернутися, як аргумент командного рядка, наприклад:
a.out 192.168.253.12
Нижче слідує текст програми
/* Простий приклад UDP клієнта для сервісу echo */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int sockfd; /* Дескриптор сокета */
int n, len; /* Змінні для різних довжин і кількості символів */
char sendline[1000], recvline[1000]; /* Масиви для посиланого і прийнятого рядка */
struct sockaddr_in servaddr, cliaddr; /* Структури для адрес серверу і клієнта */
/* Спочатку перевіряємо наявність другого аргументу в командному рядку. При його відсутності лаємося і припиняємо роботу */
if(argc != 2){
printf("Usage: a.out <IP address>\n");
exit(1);
}
/* Створюємо UDP сокет */
if((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){
реrror(NULL); /* Друкуємо повідомлення про помилку */
exit(1);
}
/* Заповнюємо структуру для адреси клієнта: сімейство протоколів TCP/IP, мережний інтерфейс – будь-хто, номер порту по розсуду операційної системи. Оскільки в структурі міститься додаткове не потрібне нам поле, яке повинне бути нульовим, перед заповненням обнуляємо її всю */
bzero(&cliaddr, sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(0);
cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* Настроюємо адресу сокета */
if(bind(sockfd (struct sockaddr *) &cliaddr
sizeof(cliaddr)) < 0){
реrror(NULL);
close(sockfd); /* Після закінчення роботи закриваємо
дескриптор сокета */
exit(1);
}
/* Заповнюємо структуру для адреси серверу: сімейство протоколів TCP/IP, мережний інтерфейс – з аргументу командного рядка, номер порту 7. Оскільки в структурі міститься додаткове не потрібне нам поле, яке повинне бути нульовим, перед заповненням обнуляємо її всю */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(7);
if(inet_aton(argv[1], &servaddr.sin_addr)== 0){
printf("Invalid IP address\n");
close(sockfd); /* Після закінчення роботи закриваємо дескриптор сокета */
exit(1);
}
/* Вводимо рядок, який відішлемо серверу */
printf("String => ");
fgets(sendline, 1000, stdin);
/* Посилаємо датаграму */
if(sendto(sockfd, sendline, strlen(sendline)+1
0 (struct sockaddr *) &servaddr
sizeof(servaddr)) < 0){
реrror(NULL);
close(sockfd);
exit(1);
}
/* Чекаємо відповіді і читаємо його. Максимальна допустима довжина датаграми– 1000 символів адреса відправника нам не потрібна */
if((n = recvfrom(sockfd, recvline, 1000, 0
(struct sockaddr *) NULL, NULL)) < 0){
реrror(NULL);
close(sockfd);
exit(1);
}
/* Друкуємо відповідь, що прийшла, і закриваємо сокет */
printf("%s\n", recvline);
close(sockfd);
return 0;
}
Лістинг 15-16.1. Програма 15–16-1.c . Простий приклад UDP клієнта для сервісу echo.
Наберіть і відкомпілюйте програму.
