Linux下的實時流媒體程式設計(RTP,RTCP,RTSP)
本文轉自:http://www.ibm.com/developerworks/cn/linux/l-mdst/
一、流媒體簡介
隨著Internet的日益普及,在網路上傳輸的資料已經不再侷限於文字和圖形,而是逐漸向聲音和視訊等多媒體格式過渡。目前在網路上傳輸音訊/視訊(Audio/Video,簡稱A/V)等多媒體檔案時,基本上只有下載和流式傳輸兩種選擇。通常說來,A/V檔案佔據的儲存空間都比較大,在頻寬受限的網路環境中下載可能要耗費數分鐘甚至數小時,所以這種處理方法的延遲很大。如果換用流式傳輸的話,聲音、影像、動畫等多媒體檔案將由專門的流媒體伺服器負責向用戶連續、實時地傳送,這樣使用者可以不必等到整個檔案全部下載完畢,而只需要經過幾秒鐘的啟動延時就可以了,當這些多媒體資料在客戶機上播放時,檔案的剩餘部分將繼續從流媒體伺服器下載。
流(Streaming)是近年在Internet上出現的新概念,其定義非常廣泛,主要是指通過網路傳輸多媒體資料的技術總稱。流媒體包含廣義和狹義兩種內涵:廣義上的流媒體指的是使音訊和視訊形成穩定和連續的傳輸流和回放流的一系列技術、方法和協議的總稱,即流媒體技術;狹義上的流媒體是相對於傳統的下載-回放方式而言的,指的是一種從Internet上獲取音訊和視訊等多媒體資料的新方法,它能夠支援多媒體資料流的實時傳輸和實時播放。通過運用流媒體技術,伺服器能夠向客戶機發送穩定和連續的多媒體資料流,客戶機在接收資料的同時以一個穩定的速率回放,而不用等資料全部下載完之後再進行回放。
由於受網路頻寬、計算機處理能力和協議規範等方面的限制,要想從Internet上下載大量的音訊和視訊資料,無論從下載時間和儲存空間上來講都是不太現實的,而流媒體技術的出現則很好地解決了這一難題。目前實現流媒體傳輸主要有兩種方法:順序流(progressive streaming)傳輸和實時流(realtime streaming)傳輸,它們分別適合於不同的應用場合。
順序流傳輸
順序流傳輸採用順序下載的方式進行傳輸,在下載的同時使用者可以線上回放多媒體資料,但給定時刻只能觀看已經下載的部分,不能跳到尚未下載的部分,也不能在傳輸期間根據網路狀況對下載速度進行調整。由於標準的HTTP伺服器就可以傳送這種形式的流媒體,而不需要其他特殊協議的支援,因此也常常被稱作HTTP流式傳輸。順序流式傳輸比較適合於高質量的多媒體片段,如片頭、片尾或者廣告等。
實時流傳輸
實時流式傳輸保證媒體訊號頻寬能夠與當前網路狀況相匹配,從而使得流媒體資料總是被實時地傳送,因此特別適合於現場事件。實時流傳輸支援隨機訪問,即使用者可以通過快進或者後退操作來觀看前面或者後面的內容。從理論上講,實時流媒體一經播放就不會停頓,但事實上仍有可能發生週期性的暫停現象,尤其是在網路狀況惡化時更是如此。與順序流傳輸不同的是,實時流傳輸需要用到特定的流媒體伺服器,而且還需要特定網路協議的支援。
二、流媒體協議
實時傳輸協議(Real-time Transport Protocol,PRT)是在Internet上處理多媒體資料流的一種網路協議,利用它能夠在一對一(unicast,單播)或者一對多(multicast,多播)的網路環境中實現傳流媒體資料的實時傳輸。RTP通常使用UDP來進行多媒體資料的傳輸,但如果需要的話可以使用TCP或者ATM等其它協議,整個RTP協議由兩個密切相關的部分組成:RTP資料協議和RTP控制協議。實時流協議(Real Time Streaming Protocol,RTSP)最早由Real Networks和Netscape公司共同提出,它位於RTP和RTCP之上,其目的是希望通過IP網路有效地傳輸多媒體資料。
2.1 RTP資料協議
RTP資料協議負責對流媒體資料進行封包並實現媒體流的實時傳輸,每一個RTP資料報都由頭部(Header)和負載(Payload)兩個部分組成,其中頭部前12個位元組的含義是固定的,而負載則可以是音訊或者視訊資料。RTP資料報的頭部格式如圖1所示:
圖1 RTP頭部格式
其中比較重要的幾個域及其意義如下:
- CSRC記數(CC) 表示CSRC標識的數目。CSRC標識緊跟在RTP固定頭部之後,用來表示RTP資料報的來源,RTP協議允許在同一個會話中存在多個數據源,它們可以通過RTP混合器合併為一個數據源。例如,可以產生一個CSRC列表來表示一個電話會議,該會議通過一個RTP混合器將所有講話者的語音資料組合為一個RTP資料來源。
- 負載型別(PT) 標明RTP負載的格式,包括所採用的編碼演算法、取樣頻率、承載通道等。例如,型別2表明該RTP資料包中承載的是用ITU G.721演算法編碼的語音資料,取樣頻率為8000Hz,並且採用單聲道。
- 序列號 用來為接收方提供探測資料丟失的方法,但如何處理丟失的資料則是應用程式自己的事情,RTP協議本身並不負責資料的重傳。
- 時間戳 記錄了負載中第一個位元組的取樣時間,接收方能夠時間戳能夠確定資料的到達是否受到了延遲抖動的影響,但具體如何來補償延遲抖動則是應用程式自己的事情。
從RTP資料報的格式不難看出,它包含了傳輸媒體的型別、格式、序列號、時間戳以及是否有附加資料等資訊,這些都為實時的流媒體傳輸提供了相應的基礎。RTP協議的目的是提供實時資料(如互動式的音訊和視訊)的端到端傳輸服務,因此在RTP中沒有連線的概念,它可以建立在底層的面向連線或面向非連線的傳輸協議之上;RTP也不依賴於特別的網路地址格式,而僅僅只需要底層傳輸協議支援組幀(Framing)和分段(Segmentation)就足夠了;另外RTP本身還不提供任何可靠性機制,這些都要由傳輸協議或者應用程式自己來保證。在典型的應用場合下,RTP一般是在傳輸協議之上作為應用程式的一部分加以實現的,如圖2所示:
圖2 RTP與各種網路協議的關係
2.2 RTCP控制協議
RTCP控制協議需要與RTP資料協議一起配合使用,當應用程式啟動一個RTP會話時將同時佔用兩個埠,分別供RTP和RTCP使用。RTP本身並不能為按序傳輸資料包提供可靠的保證,也不提供流量控制和擁塞控制,這些都由RTCP來負責完成。通常RTCP會採用與RTP相同的分發機制,向會話中的所有成員週期性地傳送控制資訊,應用程式通過接收這些資料,從中獲取會話參與者的相關資料,以及網路狀況、分組丟失概率等反饋資訊,從而能夠對服務質量進行控制或者對網路狀況進行診斷。
RTCP協議的功能是通過不同的RTCP資料報來實現的,主要有如下幾種型別:
- SR 傳送端報告,所謂傳送端是指發出RTP資料報的應用程式或者終端,傳送端同時也可以是接收端。
- RR 接收端報告,所謂接收端是指僅接收但不傳送RTP資料報的應用程式或者終端。
- SDES 源描述,主要功能是作為會話成員有關標識資訊的載體,如使用者名稱、郵件地址、電話號碼等,此外還具有向會話成員傳達會話控制資訊的功能。
- BYE 通知離開,主要功能是指示某一個或者幾個源不再有效,即通知會話中的其他成員自己將退出會話。
- APP 由應用程式自己定義,解決了RTCP的擴充套件性問題,並且為協議的實現者提供了很大的靈活性。
RTCP資料報攜帶有服務質量監控的必要資訊,能夠對服務質量進行動態的調整,並能夠對網路擁塞進行有效的控制。由於RTCP資料報採用的是多播方式,因此會話中的所有成員都可以通過RTCP資料報返回的控制資訊,來了解其他參與者的當前情況。
在一個典型的應用場合下,傳送媒體流的應用程式將週期性地產生髮送端報告SR,該RTCP資料報含有不同媒體流間的同步資訊,以及已經發送的資料報和位元組的計數,接收端根據這些資訊可以估計出實際的資料傳輸速率。另一方面,接收端會向所有已知的傳送端傳送接收端報告RR,該RTCP資料報含有已接收資料報的最大序列號、丟失的資料報數目、延時抖動和時間戳等重要資訊,傳送端應用根據這些資訊可以估計出往返時延,並且可以根據資料報丟失概率和時延抖動情況動態調整發送速率,以改善網路擁塞狀況,或者根據網路狀況平滑地調整應用程式的服務質量。
2.3 RTSP實時流協議
作為一個應用層協議,RTSP提供了一個可供擴充套件的框架,它的意義在於使得實時流媒體資料的受控和點播變得可能。總的說來,RTSP是一個流媒體表示協議,主要用來控制具有實時特性的資料傳送,但它本身並不傳輸資料,而是必須依賴於下層傳輸協議所提供的某些服務。RTSP可以對流媒體提供諸如播放、暫停、快進等操作,它負責定義具體的控制訊息、操作方法、狀態碼等,此外還描述了與RTP間的互動操作。
RTSP在制定時較多地參考了HTTP/1.1協議,甚至許多描述與HTTP/1.1完全相同。RTSP之所以特意使用與HTTP/1.1類似的語法和操作,在很大程度上是為了相容現有的Web基礎結構,正因如此,HTTP/1.1的擴充套件機制大都可以直接引入到RTSP中。
由RTSP控制的媒體流集合可以用表示描述(Presentation Description)來定義,所謂表示是指流媒體伺服器提供給客戶機的一個或者多個媒體流的集合,而表示描述則包含了一個表示中各個媒體流的相關資訊,如資料編碼/解碼演算法、網路地址、媒體流的內容等。
雖然RTSP伺服器同樣也使用識別符號來區別每一流連線會話(Session),但RTSP連線並沒有被繫結到傳輸層連線(如TCP等),也就是說在整個RTSP連線期間,RTSP使用者可開啟或者關閉多個對RTSP伺服器的可靠傳輸連線以發出RTSP 請求。此外,RTSP連線也可以基於面向無連線的傳輸協議(如UDP等)。
RTSP協議目前支援以下操作:
- 檢索媒體 允許使用者通過HTTP或者其它方法向媒體伺服器提交一個表示描述。如表示是組播的,則表示描述就包含用於該媒體流的組播地址和埠號;如果表示是單播的,為了安全在表示描述中應該只提供目的地址。
- 邀請加入 媒體伺服器可以被邀請參加正在進行的會議,或者在表示中回放媒體,或者在表示中錄製全部媒體或其子集,非常適合於分散式教學。
- 新增媒體 通知使用者新加入的可利用媒體流,這對現場講座來講顯得尤其有用。與HTTP/1.1類似,RTSP請求也可以交由代理、通道或者快取來進行處理。
三、流媒體程式設計
RTP是目前解決流媒體實時傳輸問題的最好辦法,如果需要在Linux平臺上進行實時流媒體程式設計,可以考慮使用一些開放原始碼的RTP庫,如LIBRTP、JRTPLIB等。JRTPLIB是一個面向物件的RTP庫,它完全遵循RFC 1889設計,在很多場合下是一個非常不錯的選擇,下面就以JRTPLIB為例,講述如何在Linux平臺上運用RTP協議進行實時流媒體程式設計。
3.1 環境搭建
JRTPLIB是一個用C++語言實現的RTP庫,目前已經可以執行在Windows、Linux、FreeBSD、Solaris、Unix和VxWorks等多種作業系統上。要為Linux 系統安裝JRTPLIB,首先從JRTPLIB的網站(http://lumumba.luc.ac.be/jori/jrtplib/jrtplib.html)下載最新的原始碼包,此處使用的是jrtplib-2.7b.tar.bz2。假設下載後的原始碼包儲存在/usr/local/src目錄下,執行下面的命令可以對其進行解壓縮:
[[email protected] src]# bzip2 -dc jrtplib-2.7b.tar.bz2 | tar xvf -
接下去需要對JRTPLIB進行配置和編譯:
[[email protected] src]# cd jrtplib-2.7 [[email protected] jrtplib-2.7b]# ./configure [[email protected] jrtplib-2.7b]# make
最後再執行如下命令就可以完成JRTPLIB的安裝:
[[email protected] jrtplib-2.7b]# make install
3.2 初始化
在使用JRTPLIB進行實時流媒體資料傳輸之前,首先應該生成RTPSession類的一個例項來表示此次RTP會話,然後呼叫Create()方法來對其進行初始化操作。RTPSession類的Create()方法只有一個引數,用來指明此次RTP會話所採用的埠號。清單1給出了一個最簡單的初始化框架,它只是完成了RTP會話的初始化工作,還不具備任何實際的功能。
程式碼清單1:initial.cpp
#include "rtpsession.h" int main(void) { RTPSession sess; sess.Create(5000); return 0; }
如果RTP會話建立過程失敗,Create()方法將會返回一個負數,通過它雖然可以很容易地判斷出函式呼叫究竟是成功的還是失敗的,但卻很難明白出錯的原因到底什麼。JRTPLIB採用了統一的錯誤處理機制,它提供的所有函式如果返回負數就表明出現了某種形式的錯誤,而具體的出錯資訊則可以通過呼叫RTPGetErrorString()函式得到。RTPGetErrorString()函式將錯誤程式碼作為引數傳入,然後返回該錯誤程式碼所對應的錯誤資訊。清單2給出了一個更加完整的初始化框架,它可以對RTP會話初始化過程中所產生的錯誤進行更好的處理:
程式碼清單2:framework.cpp
#include <stdio.h> #include "rtpsession.h" int main(void) { RTPSession sess; int status; char* msg; sess.Create(6000); msg = RTPGetErrorString(status); printf("Error String: %s\\n", msg); return 0; }
設定恰當的時戳單元,是RTP會話初始化過程所要進行的另外一項重要工作,這是通過呼叫RTPSession類的SetTimestampUnit()方法來實現的,該方法同樣也只有一個引數,表示的是以秒為單元的時戳單元。例如,當使用RTP會話傳輸8000Hz取樣的音訊資料時,由於時戳每秒鐘將遞增8000,所以時戳單元相應地應該被設定成1/8000:
sess.SetTimestampUnit(1.0/8000.0);
3.3 資料傳送
當RTP會話成功建立起來之後,接下去就可以開始進行流媒體資料的實時傳輸了。首先需要設定好資料傳送的目標地址,RTP協議允許同一會話存在多個目標地址,這可以通過呼叫RTPSession類的AddDestination()、DeleteDestination()和ClearDestinations()方法來完成。例如,下面的語句表示的是讓RTP會話將資料傳送到本地主機的6000埠:
unsigned long addr = ntohl(inet_addr("127.0.0.1")); sess.AddDestination(addr, 6000);
目標地址全部指定之後,接著就可以呼叫RTPSession類的SendPacket()方法,向所有的目標地址傳送流媒體資料。SendPacket()是RTPSession類提供的一個過載函式,它具有下列多種形式:
int SendPacket(void *data,int len) int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc) int SendPacket(void *data,int len,unsigned short hdrextID,void *hdrextdata, int numhdrextwords) int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc, unsigned short hdrextID,void *hdrextdata,int numhdrextwords)
SendPacket()最典型的用法是類似於下面的語句,其中第一個引數是要被髮送的資料,而第二個引數則指明將要傳送資料的長度,再往後依次是RTP負載型別、標識和時戳增量。
sess.SendPacket(buffer, 5, 0, false, 10);
對於同一個RTP會話來講,負載型別、標識和時戳增量通常來講都是相同的,JRTPLIB允許將它們設定為會話的預設引數,這是通過呼叫RTPSession類的SetDefaultPayloadType()、SetDefaultMark()和SetDefaultTimeStampIncrement()方法來完成的。為RTP會話設定這些預設引數的好處是可以簡化資料的傳送,例如,如果為RTP會話設定了預設引數:
sess.SetDefaultPayloadType(0); sess.SetDefaultMark(false); sess.SetDefaultTimeStampIncrement(10);
之後在進行資料傳送時只需指明要傳送的資料及其長度就可以了:
sess.SendPacket(buffer, 5);
3.4 資料接收
對於流媒體資料的接收端,首先需要呼叫RTPSession類的PollData()方法來接收發送過來的RTP或者RTCP資料報。由於同一個RTP會話中允許有多個參與者(源),你既可以通過呼叫RTPSession類的GotoFirstSource()和GotoNextSource()方法來遍歷所有的源,也可以通過呼叫RTPSession類的GotoFirstSourceWithData()和GotoNextSourceWithData()方法來遍歷那些攜帶有資料的源。在從RTP會話中檢測出有效的資料來源之後,接下去就可以呼叫RTPSession類的GetNextPacket()方法從中抽取RTP資料報,當接收到的RTP資料報處理完之後,一定要記得及時釋放。下面的程式碼示範了該如何對接收到的RTP資料報進行處理:
if (sess.GotoFirstSourceWithData()) { do { RTPPacket *pack; pack = sess.GetNextPacket(); // 處理接收到的資料 delete pack; } while (sess.GotoNextSourceWithData()); }
JRTPLIB為RTP資料報定義了三種接收模式,其中每種接收模式都具體規定了哪些到達的RTP資料報將會被接受,而哪些到達的RTP資料報將會被拒絕。通過呼叫RTPSession類的SetReceiveMode()方法可以設定下列這些接收模式:
- RECEIVEMODE_ALL 預設的接收模式,所有到達的RTP資料報都將被接受;
- RECEIVEMODE_IGNORESOME 除了某些特定的傳送者之外,所有到達的RTP資料報都將被接受,而被拒絕的傳送者列表可以通過呼叫AddToIgnoreList()、DeleteFromIgnoreList()和ClearIgnoreList()方法來進行設定;
- RECEIVEMODE_ACCEPTSOME 除了某些特定的傳送者之外,所有到達的RTP資料報都將被拒絕,而被接受的傳送者列表可以通過呼叫AddToAcceptList ()、DeleteFromAcceptList和ClearAcceptList ()方法來進行設定。
3.5 控制資訊
JRTPLIB是一個高度封裝後的RTP庫,程式設計師在使用它時很多時候並不用關心RTCP資料報是如何被髮送和接收的,因為這些都可以由JRTPLIB自己來完成。只要PollData()或者SendPacket()方法被成功呼叫,JRTPLIB就能夠自動對到達的RTCP資料報進行處理,並且還會在需要的時候傳送RTCP資料報,從而能夠確保整個RTP會話過程的正確性。
而另一方面,通過呼叫RTPSession類提供的SetLocalName()、SetLocalEMail()、SetLocalLocation()、SetLocalPhone()、SetLocalTool()和SetLocalNote()方法,JRTPLIB又允許程式設計師對RTP會話的控制資訊進行設定。所有這些方法在呼叫時都帶有兩個引數,其中第一個引數是一個char型的指標,指向將要被設定的資料;而第二個引數則是一個int型的數值,表明該資料中的前面多少個字元將會被使用。例如下面的語句可以被用來設定控制資訊中的電子郵件地址:
sess.SetLocalEMail("[email protected]",19);
在RTP會話過程中,不是所有的控制資訊都需要被髮送,通過呼叫RTPSession類提供的EnableSendName()、EnableSendEMail()、EnableSendLocation()、EnableSendPhone()、EnableSendTool()和EnableSendNote()方法,可以為當前RTP會話選擇將被髮送的控制資訊。
3.6 實際應用
最後通過一個簡單的流媒體傳送-接收例項,介紹如何利用JRTPLIB來進行實時流媒體的程式設計。清單3給出了資料傳送端的完整程式碼,它負責向用戶指定的IP地址和埠,不斷地傳送RTP資料包:
程式碼清單3:sender.cpp
#include <stdio.h> #include <string.h> #include "rtpsession.h" // 錯誤處理函式 void checkerror(int err) { if (err < 0) { char* errstr = RTPGetErrorString(err); printf("Error:%s\\n", errstr); exit(-1); } } int main(int argc, char** argv) { RTPSession sess; unsigned long destip; int destport; int portbase = 6000; int status, index; char buffer[128]; if (argc != 3) { printf("Usage: ./sender destip destport\\n"); return -1; } // 獲得接收端的IP地址和埠號 destip = inet_addr(argv[1]); if (destip == INADDR_NONE) { printf("Bad IP address specified.\\n"); return -1; } destip = ntohl(destip); destport = atoi(argv[2]); // 建立RTP會話 status = sess.Create(portbase); checkerror(status); // 指定RTP資料接收端 status = sess.AddDestination(destip, destport); checkerror(status); // 設定RTP會話預設引數 sess.SetDefaultPayloadType(0); sess.SetDefaultMark(false); sess.SetDefaultTimeStampIncrement(10); // 傳送流媒體資料 index = 1; do { sprintf(buffer, "%d: RTP packet", index ++); sess.SendPacket(buffer, strlen(buffer)); printf("Send packet !\\n"); } while(1); return 0; }
清單4則給出了資料接收端的完整程式碼,它負責從指定的埠不斷地讀取RTP資料包:
程式碼清單4:receiver.cpp
#include <stdio.h> #include "rtpsession.h" #include "rtppacket.h" // 錯誤處理函式 void checkerror(int err) { if (err < 0) { char* errstr = RTPGetErrorString(err); printf("Error:%s\\n", errstr); exit(-1); } } int main(int argc, char** argv) { RTPSession sess; int localport; int status; if (argc != 2) { printf("Usage: ./sender localport\\n"); return -1; } // 獲得使用者指定的埠號 localport = atoi(argv[1]); // 建立RTP會話 status = sess.Create(localport); checkerror(status); do { // 接受RTP資料 status = sess.PollData(); // 檢索RTP資料來源 if (sess.GotoFirstSourceWithData()) { do { RTPPacket* packet; // 獲取RTP資料報 while ((packet = sess.GetNextPacket()) != NULL) { printf("Got packet !\\n"); // 刪除RTP資料報 delete packet; } } while (sess.GotoNextSourceWithData()); } } while(1); return 0; }
本文原始碼 下載
四、小結
隨著多媒體資料在Internet上所承擔的作用變得越來越重要,需要實時傳輸音訊和視訊等多媒體資料的場合也將變得越來越多,如IP電話、視訊點播、線上會議等。RTP是用來在Internet上進行實時流媒體傳輸的一種協議,目前已經被廣泛地應用在各種場合,JRTPLIB是一個面向物件的RTP封裝庫,利用它可以很方便地完成Linux平臺上的實時流媒體程式設計。
相關推薦
Linux下的實時流媒體程式設計(RTP,RTCP,RTSP)
本文轉自:http://www.ibm.com/developerworks/cn/linux/l-mdst/ 一、流媒體簡介 隨著Internet的日益普及,在網路上傳輸的資料已經不再侷限於文字和圖形,而是逐漸向聲音和視訊等多媒體格式過渡。目前在網路上傳輸音訊/視訊(A
live555在Linux下最簡單地實現實時流媒體點播
通過Live555交叉編譯後執行發現,上面實現的流媒體實時通過檔案伺服器的檔案點播,沒有相關的流媒體實現方式, 但在Linux下,可以通過某些技巧實現Live555伺服器實時流媒體伺服器,並且是傻瓜式的,簡易程度不需要修改Live555下面一行程式碼。 首先,需要
流媒體傳輸協議綜述(RTP-RTCP RTSP RTMP HTTP)
在Internet上,流(Streaming)的定義非常廣泛,主要是指通過網路傳輸多媒體資料的技術總稱。 一、流媒體的定義 流媒體包含廣義和狹義兩種內涵: . 廣義流媒體 指的是使音訊和視訊形成穩定和連續的傳輸流和回放流的一系列技術、方法和協議的總稱,即流媒體技術; .
流媒體協議介紹(rtp/rtcp/rtsp/rtmp/mms/hls)
RTP 參考文件 RFC3550/RFC3551 Real-time Transport Protocol)是用於Internet上針對多媒體資料流的一種傳輸層協議。RTP協議詳細說明了在網際網路上傳遞音訊和視訊的標準資料包格式。RTP
網路流媒體協議的聯絡與區別(RTP RTCP RTSP RTMP HLS)
# 網路流媒體協議的聯絡與區別(RTP RTCP RTSP RTMP HLS) [toc] --- # 三句話簡結 ## RTP RTCP RTSP RTMP HLS區別與聯絡 **`RTP傳輸流媒體資料、RTCP對RTP進行控制,同步、RTSP發起/終止流媒體`** **`RTP和RTCP互為姐妹關
Linux串列埠程式設計教程(三)——串列埠程式設計詳(原始碼)解:http://blog.csdn.net/u011192270/article/details/48174353 Linux下的串列埠程式設計(二)----(圖文並茂,講解深刻)http://blog.csdn.net/w28252
Linux串列埠程式設計教程(三)——串列埠程式設計詳(原始碼)解:http://blog.csdn.net/u011192270/article/details/48174353 Linux下的串列埠程式設計(二)----(圖文並茂,講解深刻)http://blog.csdn.ne
Linux下的TCP/IP程式設計----多播和廣播的實現 【轉載】Linux下的TCP/IP程式設計----多播和廣播的實現
【轉載】 出處:https://blog.csdn.net/wqc_CSDN/article/details/51588769 【轉載】Linux下的TCP/IP程式設計----多播和廣播的實現
linux下C/C++ socket程式設計
簡單的linux下socket程式設計,分別基於TCP和UDP協議實現的簡單程式 linux下socket程式設計可以概括為以下幾個函式的運用: socket() bind() listen() connect() ac
Linux下的TCP/IP程式設計多播和廣播的實現
【轉載】 【轉載】Linux下的TCP/IP程式設計----多播和廣播的實現 2016年06月05日 13:54:10 兜裡有糖心裡不慌 閱
linux下實時檢視tomcat執行日誌
1、先切換到:cd usr/local/tomcat5/logs2、tail -f catalina.out3、這樣執行時就可以實時檢視執行日誌了 Ctrl+c 是退出tail命令。 順便講一下linux中tail命令 tail 命令從指定點開始將檔案寫到標準輸出.使
Linux下的c基礎程式設計——空格輸出
所謂的空格輸出就是你輸入一個字串,它每輸出一個字元中間都會有一個空格。也就是在原先的字串裡插入了空格。比如五個字元中間插入4個空格 下面我將附上我的程式碼,純屬個人編寫,其中用到了昨天我們收集的str
linux下C/C++網路程式設計基本:socket實現tcp和udp的例子
簡單的linux下socket程式設計,分別基於TCP和UDP協議實現的簡單程式 linux下socket程式設計可以概括為以下幾個函式的運用: socket() bind() listen
Linux下的串列埠程式設計例項
親測可用,移植時根據需求修改即可,轉載自:http://blog.csdn.net/w282529350/article/details/7378388 //串列埠相關的標頭檔案 #include<stdio.h> /*標準輸入輸出定義*/ #
Linux下的c基礎程式設計——氣泡排序法
今天我們來寫一下氣泡排序法,其實我也是才學的,現學現賣,大家莫要笑話! 冒泡法主要是你要熟悉它的原理。 第一點:元素一先和元素二比較判斷誰大,哪一個大就放在元素二上,挨個比較找出最大的元素放在在後面。 第二點:迴圈次數,例如10個元素,第一個元素要比較9次,第二個元素要比較
流媒體開發: RTP協議全解析(H264碼流和PS流)
1、RTP Header解析
C/C++ Linux下多執行緒程式設計 #include
1.最基礎,程序同時建立5個執行緒,各自呼叫同一個函式 #include <iostream> #include <pthread.h> //多執行緒相關操作標頭檔案,可移植眾多平臺 using namespa
Linux下的c基礎程式設計——十進位制轉二進位制(遞迴法)
今天我們來用遞迴法寫一個十進位制轉二進位制的小程式。 首先大家要明白十進位制轉二進位制的演算法。 第一步先對2進行取餘。餘數就是二進位制的最後一位。 第二步對2進行整除所得的數再進行對2取餘 第三步用遞迴迴圈往復以上過程。 例如求5的二進位制。 5先對2取餘,餘1,最後一位
window 下搭建流媒體伺服器ffmpeg nginx-rmtp-module
媒體介紹和需要下載需要軟體 2、nginx,我這裡用的是nginx-1.7.11.3-Gryphon 由於nginx原生是為linux服務的,因此官方並沒有編譯好的windows版本可以下載, 要在windows上使用nginx,要麼下載原始碼進行編譯,要麼使用其他人已經編譯好的檔案。 而要讓nginx支援
Linux下的串列埠程式設計(二)
Linxu下的串列埠程式設計(二) /************宣告:本人只是見到這篇文章對我幫助很大才轉載的,但是這個完整的程式裡面本來有語法錯誤的,現在讓我改過來了************/ ---------------------------------------
Linux下簡單的網路程式設計筆記(模擬簡單的伺服器與客戶端的通訊 1-伺服器端)
一.伺服器端 (一).建立連線的條件:伺服器必須處於監聽狀態,由客戶端發起連線請求 bind之前可新增以下程式碼解決關閉伺服器後端口仍被佔用的問題 // 設定套接字選項避免地址使用錯誤 int on=1; if((setsoc