由於某種需求,工作中需要自己要開發RTSP用戶端模擬器……這裡以DarwinStreamingServer(簡稱DSS)為例進行示範,把思路記錄下來,算是開發了一個測試載入器,也方便我以後查閱。在我之前的文章(http://www.cnblogs.com/MikeZhang/archive/2012/09/16/RTSPoverTCPUDP20120916.html )中介紹過怎樣通過TCP的方式來訪問DSS,在那個執行個體中,我用的是VLC作為用戶端,通過命令列參數進行調用的。
一、通訊連接埠分析
首先通過抓包分析確定資料通訊連接埠。
RTSP資料包:
RTP資料包:
RTCP資料包:
由圖可知,在以TCP方式訪問DSS時,RTSP資料、RTP資料和RTCP資料都是通過554連接埠進行傳輸的,所以DSS伺服器只通過554連接埠和用戶端通訊。
二、通訊過程分析
OPTIONS :查詢到伺服器所提供的方法;
DESCRIBE :得到會話描述資訊(SDP);
SETUP :提醒伺服器建立會話,並確定傳輸模式;
PLAY :用戶端發送播放請求;
TEARDOWN :用戶端發起關閉請求;
當然中間還有RTP和RTCP的互動,這裡就不敘述了。
三、模擬器實現
1、建立連結
1 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)2 s.connect((m_Vars["defaultServerIp"],m_Vars["defaultServerPort"]))
2、查詢服務器所提供的方法
向伺服器發送OPTIONS請求,得到伺服器所提供的方法。
1 s.send(genmsg_OPTIONS(m_Vars["defaultTestUrl"],seq,m_Vars["defaultUserAgent"]))2 print s.recv(m_Vars["bufLen"])
3、得到會話描述資訊
向伺服器發送DESCRIBE請求,得到SDP
1 s.send(genmsg_DESCRIBE(m_Vars["defaultTestUrl"],seq,m_Vars["defaultUserAgent"]))2 msg1 = s.recv(m_Vars["bufLen"])3 print msg1
4、提醒伺服器建立會話,並確定傳輸模式
向伺服器發送SETUP請求,通知伺服器產生session,並和伺服器確定傳輸模式等。
1 s.send(genmsg_SETUP(m_Vars["defaultTestUrl"] + "/trackID=3",seq,m_Vars["defaultUserAgent"])) 2 msg1 = s.recv(m_Vars["bufLen"]) 3 print msg1 4 seq = seq + 1 5 6 sessionId = decodeMsg(msg1)['Session'] 7 8 s.send(genmsg_SETUP2(m_Vars["defaultTestUrl"] + "/trackID=4",seq,m_Vars["defaultUserAgent"],sessionId)) 9 msg1 = s.recv(m_Vars["bufLen"])10 print msg1
5、用戶端發起播放請求
向伺服器發送PLAY請求,通知伺服器發送RTP資料。
1 s.send(genmsg_PLAY(m_Vars["defaultTestUrl"] + "/",seq,m_Vars["defaultUserAgent"],sessionId))2 msg1 = s.recv(m_Vars["bufLen"])3 print msg1
用戶端接收RTP資料
1 while True : 2 msgRcv = s.recv(m_Vars["bufLen"])3 if 0 == len(msgRcv) : break4 print len(msgRcv)
6、用戶端發起關閉請求
用戶端向伺服器發送TREADOWN請求,通知伺服器關閉。
1 s.send(genmsg_TEARDOWN(m_Vars["defaultTestUrl"] + "/",seq,m_Vars["defaultUserAgent"],sessionId))2 msg1 = s.recv(m_Vars["bufLen"])3 print msg1
完整代碼:https://gist.github.com/3974202
四、運行效果
個人見解,不足之處歡迎指出。
好,就這些了,希望對你有協助。