Rtsp Rtp Over Tcp的一点补充说明
网上对Rtsp Rtp Over Tcp的说明已经很多了,但是那些文章大都只说了如何TCP承载RTP/RTCP的,没有将说明RTSP命令是如何同RTP/RTCP在一个TCP连接上区分的,这里说明一下。
很简单,通过识别$来识别,如果数据的开头不带$,那就是RTSP信令,
如果带$,就是RTP/RTCP信道的数据,这样就区分开来了
下面是live555的代码片段,可见就是通过识别$来区分RTSP信令和RTP信道的
Boolean SocketDescriptor::tcpReadHandler1(int mask) {
// We expect the following data over the TCP channel:
// optional RTSP command or response bytes (before the first '$' character)
// a '$' character
// a 1-byte channel id
// a 2-byte packet size (in network byte order)
// the packet data.
// However, because the socket is being read asynchronously, this data might arrive in pieces.
u_int8_t c;
struct sockaddr_in fromAddress;
if (fTCPReadingState != AWAITING_PACKET_DATA) {
int result = readSocket(fEnv, fOurSocketNum, &c, 1, fromAddress);
if (result == 0) { // There was no more data to read
return False;
} else if (result != 1) { // error reading TCP socket, so we will no longer handle it
#ifdef DEBUG_RECEIVE
fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): readSocket(1 byte) returned %d (error)\n", fOurSocketNum, result);
#endif
fReadErrorOccurred = True;
fDeleteMyselfNext = True;
return False;
}
}
Boolean callAgain = True;
switch (fTCPReadingState) {
case AWAITING_DOLLAR: {
if (c == '$') {
#ifdef DEBUG_RECEIVE
fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): Saw '$'\n", fOurSocketNum);
#endif
fTCPReadingState = AWAITING_STREAM_CHANNEL_ID;
} else {
// This character is part of a RTSP request or command, which is handled separately:
if (fServerRequestAlternativeByteHandler != NULL && c != 0xFF && c != 0xFE) {
// Hack: 0xFF and 0xFE are used as special signaling characters, so don't send them
(*fServerRequestAlternativeByteHandler)(fServerRequestAlternativeByteHandlerClientData, c);
}
}
break;
}