Как заставить клиента переключать транспорт RTP с UDP на TCP?
Если клиент хочет посмотреть поток, который находится на моем RTSP-сервере, он сначала пытается настроить поток по протоколу UDP. Как я могу сказать, что мой сервер поддерживает только RTP/AVP/TCP и что он должен переключать транспорты?
Я хочу прекратить поддержку UDP на моем сервере, но все клиенты сначала пытаются УСТАНОВИТЬ сеанс по UDP, а затем они делают это по TCP... и я хочу переключить их на TCP как можно скорее в протоколе RTSP.
Как я могу это сделать?
6 ответов
OK, один из способов - отправить "400 Bad Request" в качестве ответа на запрос SETUP клиента... и он автоматически переключается на протокол TCP. Это для RealOne и QuickTime.
Но я не уверен, что это будет работать на всех других игроках, так как это взлом.
Есть другие идеи? =|
Насколько я знаю, на стороне сервера нет контроля над типом транспорта. Сервер должен быть универсальным, он должен поддерживать RTP через UDP, RTP через TCP, RTP через RTSP и RTP через RTSP через HTTP(S). И его клиенты выбирают, какой транспорт выбрать. Транспортное поле сначала отправляется в запросе SETUP
1) UDP
C->A: SETUP rtsp://audio.example.com/twister/audio.en RTSP/1.0
CSeq: 1
Transport: RTP/AVP/UDP;unicast;client_port=3056-3057
2) TCP
C->A: SETUP rtsp://audio.example.com/twister/audio.en RTSP/1.0
CSeq: 1
Transport: RTP/AVP/TCP;unicast;client_port=3056-3057
3) RTP через RTSP и RTP через RTSP через HTTP (S)
S->C: RTSP/1.0 200 OK
CSeq: 2
Date: 05 Jun 1997 18:57:18 GMT
Transport: RTP/AVP/TCP;interleaved=0-1
Как мы видим, запрос "Тип транспорта" отправляется клиентской стороной.
Если вы хотите поддерживать только TCP-сервер, вы можете отправить "400 Bad Request" или "461 Unsupported transport" в ответ на запрос SETUP, как вы предлагаете, или другой способ - отправить 200 OK, но не передавать пакеты RTP. Клиент истечет время ожидания и узнает, что он находится за прокси-сервером и снова отправит запрос SETUP с параметром RTP/AVP/TCP (не идеальный случай).
Чтобы расширить ответ для Android, для клиентов Android, они всегда будут пытаться установить UDP-соединение в первую очередь.
Как для OpenCore, так и для StageFright я могу подтвердить, что если я верну "461 Unsupported Transport" с моего сервера в ответ на первый запрос SETUP для передачи UDP, оба этих клиента будут НЕМЕДЛЕННО пытаться установить TCP-соединение через порт RTSP.
Все остальные ответы подробно описаны здесь: http://www.ietf.org/rfc/rfc2326.txt
Если вы использовали ffmpeg, вы можете принудительно переключить протокол транспортного уровня rtsp.
av_dict_set(&format_opts, "rtsp_transport", "tcp", 0);
err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
Вы можете попытаться передать заголовок "transport" в ответе на запрос "Describe" и указать, что ваш сервер поддерживает только транспорт RTP/AVP/TCP, и клиент должен знать, что UDP не поддерживается.
Какой клиент подключается к вашему серверу? Некоторые клиенты могут быть запущены с помощью метода URI в URL. Например, вы можете указать rtspt://myhost/path.sdp.
Если у вас есть контроль над клиентом / серверами, вы можете использовать заголовок Require на клиентах и Unsupported на серверах, чтобы указать, что UDP не поддерживается; но большинство клиентов, которых я видел, не используют это.