70: /* Родительский процесс. Он получает файловый дескриптор. */
71: int parentProcess(int sock) {
72: char buf[80]; /* пространство для передачи имени файла */
73: struct iovec vector; /* имя файла от дочернего процесса */
74: struct msghdr msg; /* полное сообщение */
75: struct cmsghdr * cmsg; /* управляющее сообщение с fd */
76: int fd;
77:
78: /* установка iovec для имени файла */
79: vector.iov_base = buf;
80: vector.iov_len = 80;
81:
82: /* сообщение, которое мы хотим получить */
83:
84: msg.msg_name = NULL;
85: msg.msg_namelen = 0;
86: msg.msg_iov = &vector
87: msg.msg_iovlen = 1;
88:
89: /* динамическое распределение (чтобы мы могли выделить участок
90: памяти для файлового дескриптора) */
91: cmsg = alloca(sizeof(struct cmsghdr) + sizeof(fd));
92: cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(fd);
93: msg.msg_control = cmsg;
94: msg.msg_controllen = cmsg->cmsg_len;
95:
96: if (!recvmsg(sock, &msg, 0))
97: return 1;
98:
99: printf("получен файловый дескриптор для '%s'\n",
100: (char *) vector.iov_base);
101:
102: /* присвоение файлового дескриптора из управляющей структуры */
103: memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
104:
105: copyData(fd, 1);
106:
107: return 0;
108: }
109:
110: int main(int argc, char ** argv) {
111: int socks[2];
112: int status;
113:
114: if (argc != 2) {
115: fprintf(stderr, "поддерживается только один аргумент\n");
116: return 1;
117: }
118:
119: /* Создание сокетов. Один служит для родительского процесса,
120: второй — для дочернего (мы можем поменять их местами,
121: если нужно). */
122: if (socketpair(PF_UNIX, SOCK_STREAM, 0, socks))
123: die("socketpair");
124:
125: if (!fork()) {
126: /* дочерний процесс */
127: close(socks[0]);
128: return childProcess(argv[1], socks[1]);
129: }
130:
131: /* родительский процесс */
132: close(socks[1]);
133: parentProcess(socks[0]);
134:
135: /* закрытие дочернего процесса */
136: wait(&status);
137:
138: if (WEXITSTATUS(status))
139: fprintf(stderr, "childfailed\n");
140:
141: return 0;
142: }
17.5. Сетевая обработка с помощью TCP/IP
Самое важное применение сокетов заключается в том, что они позволяют приложениям, работающим на основе различных механизмов, общаться друг с другом. Семейство протоколов TCP/IP [34] используется в Internet самым большим в мире числом компьютеров, объединенных в сеть. Система Linux предлагает полную устойчивую реализацию TCP/IP, которая позволяет действовать и как сервер, и как клиент TCP/IP.
Наиболее распространенной версией TCP/IP является версия 4 (IPv4). В данный момент для большинства операционных систем и продуктов сетевой инфраструктуры уже доступна версия 6 протокола TCP/IP (IPv6), однако IPv4 доминирует до сих пор. В данном разделе мы сосредоточимся на создании приложений для IPv4, но обратим внимание на отличия для приложений IPv6, а также для тех программ, которые должны поддерживать обе версии.
17.5.1. Упорядочение байтов