1. 程式人生 > >linux網路程式設計之RTP協議

linux網路程式設計之RTP協議

以下內容取自:

本機通訊:
https://www.cnblogs.com/lidabo/p/4160138.html(RTP協議傳輸)
https://www.cnblogs.com/lidabo/p/4160145.html(RTP協議傳輸)

非本機:http://velep.com/archives/934.html(關於伺服器ip的傳輸方法)

下載ffmpeg出錯了於是從csdn上下載了一些ts格式的視訊。測試環境是ubuntu16.04,VLC安裝在ubuntu上,但如果用windows的VLC是無法通過訪問ubuntu機子的靜態ip獲取到視訊的,因為沒有繫結特定的伺服器ip。

其中的python檔案用於獲取到rtp協議的欄位的值,VLC上的流設定:

根據獲取到的值來為c程式設計中模擬rtp協議頭:

80解析為1000 0000,也就是V:10(也就是值為2),P:0,X:0,CC:0。

第四列為遞增的,也就是sequence_number。

其中的rtp_header格式考慮到本機位元組序與網路位元組序問題每個位元組裡的位反過來宣告。注意unsigned short為16,unsigned int為32。

由於sequence需要滿足遞增的規律並且考慮到位元組序的問題,因此需要htons()和ntohs()。

要使用域名訪問的話將其改為:

新增一個頭檔案<arpa/inet.h>

,再定義一個udp_ip為伺服器的ip地址,再將dest_addr.sin_sddr.s_addr=INADDR_ANY改為dest_addr.sin_addr.s_addr=inet_addr(UDP_SERVER_IP)即可。

但是我這裡的windows上的vlc訪問192.168.157.10:6666(我的虛擬機器的ip)會卡死,可能是流的問題?ping是能ping通的,不太清楚原因,以後再看。

這裡看一下sendto和recvfrom函式:

客戶端需要宣告要傳送資訊給到的伺服器端的ip,伺服器端則定義INADDR_ANY就好。客戶端和伺服器端需要宣告同樣的端口才好進行通訊。

//buf初始化:
bzero(buf,sizeof(buf));

//訊息傳送的主要操作:
len=recvfrom((int)sockfd,(void *)buf,sizeof(buffer),(unsigned int)flags,(struct sockaddr*)from,int *fromlen);//這裡的buf也就是傳回來的內容,可以直接print。注意最後一個引數要取址。

sendto((int)sockfd,(const void*)buffer,sizeof(buffer),(unsigned int)flags,(const struct sockaddr*)to,int tolen);//這個函式用到const應該是避免傳輸過程中修改傳送端的資料。

//由使用者傳送訊息的一端需要有讀取字元裝置的操作:
len=read(STDIN_FILENO,buf,sizeof(buf));

//sockaddr和sockaddr_in的關係:
其實是一樣的可以互相轉化,所佔記憶體也是一樣大的,賦值的時候我們用到sockaddr_in,函式呼叫就用sockaddr。