Книга: UNIX: разработка сетевых приложений
10.7. Управление завершением соединения
Разделы на этой странице:
10.7. Управление завершением соединения
В наших примерах на клиента была возложена ответственность по завершению ассоциации, для чего ему приходилось закрывать сокет. Но закрытие сокета не всегда является желаемой операцией с точки зрения приложения. Кроме того, серверу не нужно оставлять ассоциацию открытой после отправки эхо-ответа. В описанных ситуациях применяются альтернативные механизмы завершения ассоциации. Для сокетов типа «один-ко-многим» доступно два метода: корректное и аварийное закрытие.
Если сервер хочет закрыть ассоциацию после отправки сообщения, он должен добавить флаг MSG_EOF в это сообщение, поместив его в поле sinfo_flags
структуры sctp_sndrcvinfo
. Этот флаг закрывает ассоциацию после подтверждения приема отсылаемого сообщения. Альтернативный метод состоит в установке флага MSG_ABORT
в том же поле sinfo_flags
. При этом происходит немедленное закрытие ассоциации с отправкой порции ABORT (аналог TCP-сегмента RST). Данные, находящиеся в буфере отправки, сбрасываются. Однако закрытие сеанса SCTP порцией ABORT не приводит к негативным последствиям типа пропущенного состояния TIME_WAIT, как это происходит в TCP. В листинге 10.7 показана новая версия эхо-сервера, инициирующая корректное завершение соединения одновременно с отправкой эхо-ответа клиенту. В листинге 10.8 показана версия клиента, отправляющая порцию ABORT перед закрытием сокета.
Листинг 10.7. Сервер, закрывающий ассоциацию после отправки ответа
//sctp/sctpserv03.c
25 for (;;) {
26 len = sizeof(struct sockaddr_in);
27 rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
28 (SA*)&cliaddr, &len, &sri, &msg_flags);
29 if (stream_increment) {
30 sri.sinfo_stream++;
31 if (sri.sinfo_stream >=
32 sctp_get_no_strms(sock_fd, (SA*)&cliaddr, len))
33 sri.sinfo_stream = 0;
34 }
35 Sctp_sendmsg(sock_fd, readbuf, rd_sz,
36 (SA*)&cliaddr, len,
37 sri.sinfo_ppid,
38 (sri.sinfo_flags | MSG_EOF), sri.sinfo_stream, 0, 0);
39 }
Отправка ответа с закрытием ассоциации
38
Изменение кода сервера состоит в том, что мы добавляем флаг MSG_EOF
к прочим флагам в вызове sctp_sendmsg
операцией логического ИЛИ. Благодаря этому сервер закрывает ассоциацию после подтверждения доставки сообщения.
Листинг 10.8. Клиент, выполняющий аварийное закрытие ассоциации
//sctp/sctpclient02.c
25 if (echo_to_all == 0)
26 sctpstr_cli(stdin, sock_fd, (SA*)&servaddr, sizeof(servaddr));
27 else
28 sctpstr_cli_echoall(stdin, sock_fd, (SA*)&servaddr,
29 sizeof(servaddr));
30 strcpy(byemsg, "goodbye");
31 Sctp_sendmsg(sock_fd, byemsg, strlen(byemsg),
32 (SA*)&servaddr, sizeof(servaddr), 0, MSG_ABORT, 0, 0, 0);
33 Close(sock_fd);
Аварийное закрытие ассоциации
30-32
Клиент подготавливает сообщение об аварийном закрытии ассоциации, вызванном пользовательской ошибкой. Затем функция sctp_sendmsg
вызывается с флагом MSG_ABORT
. При этом отправляется порция данных ABORT, что приводит к немедленному закрытию ассоциации. В порцию данных включается код пользовательской ошибки и сообщение («goodbye») в поле причины ошибки вышележащего уровня.
Закрытие дескриптора сокета
33
Хотя ассоциация и была завершена, дескриптор сокета все равно закрыть нужно, чтобы освободить связанные с ним системные ресурсы.
- 10.1. Введение
- 10.2. Потоковый эхо-сервер SCTP типа «один-ко-многим»: функция main
- 10.3. Потоковый эхо-клиент SCTP типа «один-ко-многим»: функция main
- 10.4. Потоковый эхо-клиент SCTP: функция str_cli
- 10.5. Блокирование очереди
- 10.6. Управление количеством потоков
- 10.7. Управление завершением соединения
- 10.8. Резюме
- Упражнения
- Глава 10 Пример SCTP-соединения клиент-сервер
- Глава 11. Соединения точка-точка и ретрансляторы
- УПРАВЛЕНИЕ РЕПУТАЦИЕЙ В ИНТЕРНЕТЕ
- 2. Операции декартового произведения и естественного соединения
- 4. Варианты операций соединения
- 5. Операции внутреннего соединения.
- 6. Операция естественного соединения.
- 7. Операция левого внешнего соединения.
- 8. Операция правого внешнего соединения.
- 9. Операция полного внешнего соединения.
- Глава 7 Управление хранилищем данных
- Глава 11 Корпоративное управление и стратегия