Адрес | Протокол | Описание протокола |
---|---|---|
AF_UNIX | PF_UNIX | Домен Unix. |
AF_INET | PF_INET | TCP/IP (версия 4). |
AF_INET6 | PF_INET6 | TCP/IP (версия 6). |
AF_AX25 | PF_AX25 | AX.25, используется радиолюбителями. |
AF_IPX | PF_IPX | Novell IPX. |
AF_APPLETALK | PF_APPLETALK | AppleTalk DDS. |
AF_NETROM | PF_NETROM | NetROM, используется радиолюбителями. |
17.2. Служебные функции
Во всех примерах этого раздела используются две функции: copyData()
и die()
. Функция copyData()
считывает данные из одного файлового дескриптора и записывает их в какой-то другой дескриптор (до тех пор, пока имеются данные для чтения). Функция die()
вызывает perror()
и завершает программу. Мы ввели обе указанные функции в файл sockutil.с
для того, чтобы сделать обучающие программы немного проще. Для справки ниже показана реализация двух данных функций.
1: /* sockutil.с */
2:
3: #include
4: #include
5: #include
6:
7: #include "sockutil.h"
8:
9: /* выдает сообщение об ошибке через функцию perror() и прекращает работу программы */
10: void die(char * message) {
11: perror(message);
12: exit(1);
13: }
14:
15: /* Копирует данные из дескриптора файла 'from' в дескриптор файла
16: 'to' до полного завершения копирования. Выходит из программы, если
17: происходит ошибка. Предполагается, что для обоих файлов установлено
18: блокирующее чтение и запись. */
19: void copyData(int from, int to) {
20: char buf[1024];
21: int amount;
22:
23; while ((amount = read(from, buf, sizeof(buf))) > 0) {
24: if (write(to, buf, amount) != amount) {
25: die("write");
26: return;
27: }
28: }
29: if (amount < 0)
30: die("read");
31: }
17.3. Основные действия с сокетами
Подобно большинству остальных ресурсов Linux сокеты реализуются через файловую абстракцию. Они создаются при помощи системного вызова socket()
, который возвращает файловый дескриптор. После соответствующей инициализации сокета данный дескриптор может использоваться для запросов read()
и write()
, как и любой другой файловый дескриптор. Когда процесс завершает работу с сокетом, его необходимо закрыть через функцию close()
для того, чтобы освободить все ресурсы, ассоциированные с ним.
В настоящем разделе представлены основные системные вызовы для создания и инициализации сокетов для любого протокола. Для того чтобы не зависеть от протоколов, информация в некоторой степени абстрагирована, по этой же причине мы не приводим примеры. Следующие два раздела посвящены применению сокетов в двух различных протоколах (домен Unix и TCP/IP). Здесь вы найдете подробные примеры использования большинства системных вызовов, описанных ниже.
17.3.1. Создание сокета
Новые сокеты создаются системным вызовом socket()
, который возвращает файловый дескриптор для
#include
int socket(int domain, int type, int protocol);
Подобно open()
, функция socket()
возвращает значение меньше 0, если имела место ошибка, и файловый дескриптор, больший или равный нулю, если все прошло благополучно. Три параметра устанавливают протокол, который нужно использовать.
Первый параметр указывает семейство протоколов и, как правило, принимает одно из значений, перечисленных в табл. 17.1.