3个版本:
1、101259341rtsp-3518e-ov9712(貌似官方示例)
2、朱给出的rtsp服务器
用wireshark软件打开0106.pcapng,发现有一堆的抓包数据,我们点击上面的过滤栏里右边的表达式,选择RTSP,再点击旁边的箭头,就会过滤出RTSP包,界面如下图:
Live555库是一个使用开放标准协议如RTP/RTCP、RTSP、SIP等实现多媒体流式传输的开源C 库集。这些函数库可以在Unix、Windows、QNX等操作系统下编译使用,基于此建立RTSP/SIP服务器和客户端来实现多媒体流的传输。下面给出具体实现过程[4]:
(1)客户端发起RTSP OPTION请求,目的是得到服务器提供什么方法。RTSP提供的方法一般包括OPTIONS、DESCRIBE、SETUP、TEARDOWN、PLAY、PAUSE、SCALE、GET_PARAMETER。
(2)服务器对RTSP OPTION回应,服务器实现什么方法就回应哪些方法。在此系统中,我们只对DESCRIBE、SETUP、TEARDOWN、PLAY方法做了实现。
(3)客户端发起RTSP DESCRIBE请求,服务器收到的信息主要有媒体的名字,解码类型,视频分辨率等描述,目的是为了从服务器那里得到会话描述信息(SDP)。
(4)服务器对RTSP DESCRIBE响应,发送必要的媒体参数,在传输H.264文件时,主要包括SPS/PPS、媒体名、传输协议等信息。
(5)客户端发起RTSP SETUP请求,目的是请求会话建立并准备传输。请求信息主要包括传输协议和客户端端口号。
(6)服务器对RTSP SETUP响应,发出相应服务器端的端口号和会话标识符。
(7)客户端发出了RTSP PLAY的请求,目的是请求播放视频流。
(8)服务器对RTSP PLAY响应,响应的消息包括会话标识符,RTP包的序列号,时间戳。此时服务器对H264视频流封装打包进行传输。
(9)客户端发出RTSP TEARDOWN请求,目的是关闭连接,终止传输。
(10)服务器关闭连接,停止传输。
以上我们知道RTSP协议的握手顺序,具体分析还要看代码。我们前面说过main线程里EventLoop()函数进行检查是否有RTSP连接请求。
主函数循环:接受客户端请求 + 处理ScheduleConnections
//输入为之前s32MainFd = tcp_listen(SERVER_RTSP_PORT_DEFAULT);创建的服务器套接字
void EventLoop(int s32MainFd)
{
// static unsigned int s32ChdCnt=0;
static int s32ConCnt = 0;//已经连接的客户端数
int s32Fd = -1;
static RTSP_buffer *pRtspList=NULL;
RTSP_buffer *p=NULL;
unsigned int u32FdFound;
/*接收连接,创建一个新的socket*/
if (s32ConCnt!=-1){
/*接收新连接,创建一个新的socket,返回其描述符*/
//无阻塞查询是否有连接,有连接时返回值>0,无连接时返回值<0
s32Fd= tcp_accept(s32MainFd); //非阻塞
}
/*处理新创建的连接*/
if (s32Fd >= 0){
/*查找列表中是否存在此连接的socket*/
for (u32FdFound=0,p=pRtspList; p!=NULL; p=p->next)
{
if (p->fd == s32Fd)
{
u32FdFound=1;
break;
}
}
if (!u32FdFound)
{
/*创建一个连接,增加一个客户端*/
if (s32ConCnt<MAX_CONNECTION){
++s32ConCnt;
//将新连接添加到链表里,并初始化其会话
AddClient(&pRtspList,s32Fd);
}
else
{
fprintf(stderr, "exceed the MAX client, ignore this connecting\n");
return;
}
num_conn++;
fprintf(stderr, "%s Connection reached: %d\n", __FUNCTION__, num_conn);
}
}
/*对已有的连接进行调度*/
ScheduleConnections(&pRtspList,&s32ConCnt);
}
EventLoop()
1、如果由tcp_accept调用网络编程accept函数(无阻塞),如果不在列表中就AddClient添加进客户端列表(malloc添加到链表尾部)
2、ScheduleConnections(&pRtspList,&s32ConCnt);
ScheduleConnections函数
void ScheduleConnections(RTSP_buffer **rtsp_list, int *conn_count)
{
int res;
RTSP_buffer *pRtsp=*rtsp_list,*pRtspN=NULL;
RTP_session *r=NULL, *t=NULL;
#ifdef RTSP_DEBUG
// fprintf(stderr, "%s\n", __FUNCTION__);
#endif
while (pRtsp!=NULL)
{
if ((res = RtspServer(pRtsp