Linux課程設(shè)計(jì)-網(wǎng)絡(luò)音頻點(diǎn)播器_第1頁(yè)
Linux課程設(shè)計(jì)-網(wǎng)絡(luò)音頻點(diǎn)播器_第2頁(yè)
Linux課程設(shè)計(jì)-網(wǎng)絡(luò)音頻點(diǎn)播器_第3頁(yè)
Linux課程設(shè)計(jì)-網(wǎng)絡(luò)音頻點(diǎn)播器_第4頁(yè)
Linux課程設(shè)計(jì)-網(wǎng)絡(luò)音頻點(diǎn)播器_第5頁(yè)
已閱讀5頁(yè),還剩22頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Linux課程設(shè)計(jì)報(bào)告Linux課程設(shè)計(jì)報(bào)告報(bào)告題目: 網(wǎng)絡(luò)音頻點(diǎn)播器 作者所在系部: 計(jì)算機(jī)科學(xué)與遙感信息技術(shù)學(xué)院 作者所在專業(yè): 計(jì)算機(jī)科學(xué)與技術(shù) 作者所在班級(jí): B12511 作 者 姓 名 : 王碩 作 者 學(xué) 號(hào) : 20124051117 指導(dǎo)教師姓名: 王慧娟 完 成 時(shí) 間 : 2015年6月29日 Linux課程設(shè)計(jì)報(bào)告Linux下C語(yǔ)言高級(jí)編程課程設(shè)計(jì)任務(wù)書一、設(shè)計(jì)目的本課程設(shè)計(jì)是學(xué)生學(xué)習(xí)完Linux C高級(jí)編程課程后,進(jìn)行的一次全面的綜合訓(xùn)練,通過(guò)課程設(shè)計(jì),讓學(xué)生更好地掌握操作系統(tǒng)的原理及實(shí)現(xiàn)方法,加深對(duì)操作系統(tǒng)基礎(chǔ)理論和重要算法的理解,加強(qiáng)學(xué)生的動(dòng)手能力。二、課程設(shè)計(jì)基

2、本要求每人從所給題目中任選一個(gè)(如自擬題目,需經(jīng)教師同意,可以多選,鼓勵(lì)多做),每個(gè)學(xué)生必須獨(dú)立完成課程設(shè)計(jì),不能相互抄襲;設(shè)計(jì)完成后,將所完成的工作交由老師檢查;要求寫出一份詳細(xì)的設(shè)計(jì)報(bào)告。三、設(shè)計(jì)內(nèi)容及設(shè)計(jì)要求題目一: 基于Linux的網(wǎng)絡(luò)實(shí)時(shí)音頻組播系統(tǒng)網(wǎng)絡(luò)音頻多播系統(tǒng)有客戶端和服務(wù)器兩部分組成。服務(wù)器主要負(fù)責(zé)把不同頻道的數(shù)據(jù)發(fā)送到相應(yīng)的多播組,服務(wù)器采用多線程模型以提高運(yùn)行質(zhì)量,音頻數(shù)據(jù)使用流媒體。客戶端采用多進(jìn)程模式,進(jìn)程間通信方式采用管道或者本地套接字,主進(jìn)程負(fù)責(zé)從多播組接收數(shù)據(jù)并寫入管道,子進(jìn)程從管道中讀出數(shù)據(jù)并調(diào)用播放器播放音頻。題目二:基于Linux的企業(yè)內(nèi)部通信工具企業(yè)內(nèi)部

3、通信工具由客戶端和服務(wù)器組成,多個(gè)客戶端對(duì)應(yīng)一個(gè)服務(wù)器,該項(xiàng)目能夠保證公司的秘密資料只在公司內(nèi)部流動(dòng),并且能夠讓員工之間方便通信。服務(wù)器包括注冊(cè)處理、聊天處理、登陸處理、傳輸文件處理四個(gè)模塊??蛻舳税ㄗ?cè)、登陸、聊天、傳輸文件四個(gè)模塊??蛻舳酥g的通信由服務(wù)器轉(zhuǎn)發(fā)并做好記錄。題目三:自擬題目要符合課程設(shè)計(jì)的難度和工作量(要求學(xué)生如自擬題目提前與老師溝通)。 四、課程設(shè)計(jì)考核方式課程設(shè)計(jì)成績(jī)?cè)u(píng)定的依據(jù)有設(shè)計(jì)文檔資料、具體實(shí)現(xiàn)設(shè)計(jì)方案的程序及課程設(shè)計(jì)考勤登記表,其中平時(shí)成績(jī)占總成績(jī)的20%。(注:最后需要驗(yàn)收)優(yōu):有完整的符合標(biāo)準(zhǔn)的文檔,文檔有條理、文筆通順,格式正確,其中有總體設(shè)計(jì)思想的論述;

4、程序完全實(shí)現(xiàn)設(shè)計(jì)方案,設(shè)計(jì)方案先進(jìn),軟件可靠性好;良:有完整的符合標(biāo)準(zhǔn)的文檔,文檔有條理、文筆通順,格式正確;有完全實(shí)現(xiàn)設(shè)計(jì)方案的軟件,設(shè)計(jì)方案較先進(jìn);中:有完整的符合標(biāo)準(zhǔn)的文檔,有基本實(shí)現(xiàn)設(shè)計(jì)方案的軟件,設(shè)計(jì)方案正確;及格:有完整的符合標(biāo)準(zhǔn)的文檔,有基本實(shí)現(xiàn)設(shè)計(jì)方案的軟件,設(shè)計(jì)方案基本正確;不及格:沒(méi)有完整的符合標(biāo)準(zhǔn)的文檔,軟件沒(méi)有基本實(shí)現(xiàn)設(shè)計(jì)方案,設(shè)計(jì)方案不正確。提交的電子文檔和軟件必須是由學(xué)生自己獨(dú)立完成,雷同者教師有權(quán)視其情況扣分或記零分。五、提交的資料1、文檔有關(guān)的分析設(shè)計(jì)文檔要求使用計(jì)算機(jī)打印A4紙上,同時(shí)提交電子文檔。2、軟件軟件需提供加注釋的源程序,并能正常運(yùn)行。注:對(duì)于分析設(shè)

5、計(jì)中未能實(shí)現(xiàn)的部分需要加以說(shuō)明。對(duì)于軟件中所參考的部分模塊或代碼需要加以聲明,并說(shuō)明出處。摘 要 隨著Internet的日益普及,在網(wǎng)絡(luò)上學(xué)會(huì)配置網(wǎng)絡(luò)服務(wù)器,有著非常重要的意義。綜合網(wǎng)絡(luò)服務(wù)器基于Linux操作系統(tǒng)之上,進(jìn)行服務(wù)器與客戶端的連接,實(shí)現(xiàn)服務(wù)器為客戶端提供服務(wù)。其實(shí)訓(xùn)內(nèi)容包括Linux服務(wù)器搭建與測(cè)試,服務(wù)器搭建與應(yīng)用網(wǎng)絡(luò)訪問(wèn),以及流控令牌桶等等。綜合網(wǎng)絡(luò)服務(wù)器的功能強(qiáng)大,操作簡(jiǎn)單,擴(kuò)展性強(qiáng),穩(wěn)定性高;方便不同操作系統(tǒng)平臺(tái)之間的移植,網(wǎng)站最大限度的實(shí)現(xiàn)易維護(hù)和易操作性。Linux是一套免費(fèi)使用和自由傳播的操作系統(tǒng),以其穩(wěn)定性和靈活性著稱。完善的內(nèi)置網(wǎng)絡(luò)是Linux的一大特點(diǎn)。Lin

6、ux為用戶提供了完善的、強(qiáng)大的網(wǎng)絡(luò)功能。作為一種網(wǎng)絡(luò)操作系統(tǒng),它在網(wǎng)絡(luò)服務(wù)器上得到了廣泛的應(yīng)用。關(guān)鍵詞: 域名訪問(wèn)、Linux、網(wǎng)絡(luò)服務(wù)器、服務(wù)器配置目 錄第1章 系統(tǒng)分工- 1 -1.1系統(tǒng)總體功能簡(jiǎn)介- 1 -1.2實(shí)驗(yàn)內(nèi)容- 1 -第2章 系統(tǒng)的總體設(shè)計(jì)- 2 -2.1技術(shù)支持- 2 -2.2設(shè)計(jì)方案- 2 -2.3服務(wù)器概述- 2 -2.4 客戶端概述- 3 -第3章 服務(wù)器設(shè)計(jì)- 4 -3.1管道- 4 -3.2令牌桶TBF流控- 4 - 3.3創(chuàng)建頻道鏈表- 4 -3.4頻道廣播- 5 -3.5數(shù)據(jù)發(fā)送- 6 -第4章 客戶端設(shè)計(jì)- 7 -4.1選擇頻道- 7 -4.2接收數(shù)據(jù)-

7、8 -第5章 系統(tǒng)調(diào)試- 9 -5.1 系統(tǒng)的調(diào)試- 9 -5.2 客戶端調(diào)試- 9 -5.3 服務(wù)器調(diào)試- 10 -第6章 總結(jié)- 12 -系統(tǒng)使用說(shuō)明書- 13 -部分代碼說(shuō)明:- 13 -.H文件- 13 -Proto.h- 13 -site_types.h- 14 -Client端:- 14 -Server端:- 19 -評(píng)語(yǔ)- 22 -成績(jī):- 22 - 3 -第1章 系統(tǒng)分工1.1系統(tǒng)總體功能簡(jiǎn)介 本軟件實(shí)現(xiàn)了基于客戶機(jī)和服務(wù)器模型的網(wǎng)絡(luò)音頻點(diǎn)播系統(tǒng),是嵌入式系統(tǒng)在音頻領(lǐng)域中的一個(gè)典型應(yīng)用。本音頻點(diǎn)播系統(tǒng)可以廣泛應(yīng)用在卡拉OK廳、語(yǔ)音教室和公共廣播等多種場(chǎng)所。該軟件分為服務(wù)器和客戶

8、機(jī)兩個(gè)部分,服務(wù)器運(yùn)行在PC機(jī)上,客戶機(jī)運(yùn)行在嵌入式設(shè)備上,服務(wù)器以多播的方式向局域網(wǎng)中所有的客戶機(jī)發(fā)送數(shù)據(jù),客戶機(jī)可以根據(jù)自己的選擇來(lái)決定要接收的數(shù)據(jù)。1.2實(shí)驗(yàn)內(nèi)容 在VMware Workstation 11.0平臺(tái)下,使用Red Hat Enterprise Linux 6.2終端,基于socket開發(fā)網(wǎng)絡(luò)音頻點(diǎn)播程序,服務(wù)端能夠捕捉音頻流并發(fā)送到需要點(diǎn)播的客戶端,客戶端接收到音頻并播放,并且客戶端可以自由切換頻道。 第2章 系統(tǒng)的總體設(shè)計(jì)2.1技術(shù)支持虛擬機(jī)環(huán)境:VMware Workstation 11.0Linux系統(tǒng): Red Hat Enterprise Linux 6.2

9、2.2設(shè)計(jì)方案 該軟件分為服務(wù)器和客戶機(jī)兩個(gè)部分,服務(wù)器運(yùn)行在PC機(jī)上,客戶機(jī)運(yùn)行在嵌入式設(shè)備上,服務(wù)器以多播的方式向局域網(wǎng)中所有的客戶機(jī)發(fā)送數(shù)據(jù),客戶機(jī)可以根據(jù)自己的選擇來(lái)決定要接收的數(shù)據(jù),示意圖如圖2-1所示。圖2-1 總體布局2.3服務(wù)器概述 音頻的捕捉:開始父進(jìn)程建立一個(gè)匿名管道用于父子進(jìn)程之間的通信,建立一個(gè)臨時(shí)文件用于當(dāng)作接收音樂(lè)數(shù)據(jù)的緩存文件。 音頻數(shù)據(jù)的緩存:令牌桶TBF流控,由于本設(shè)計(jì)是在局域網(wǎng)中實(shí)現(xiàn)的,如果不限速的話會(huì)因服務(wù)器發(fā)送數(shù)據(jù)太快而使客戶機(jī)音樂(lè)播放失真,因此加入了令牌桶TBF限速技術(shù),限速的原理是根據(jù)mp3音樂(lè)的播放碼率控制服務(wù)器父進(jìn)程單位時(shí)間內(nèi)寫入管道的數(shù)據(jù)流,這

10、樣配合上述的管道就可實(shí)現(xiàn)與mp3音樂(lè)播放速度相同的數(shù)據(jù)流發(fā)送。 多客戶支持和管理:能夠支持多個(gè)客戶機(jī)同時(shí)接收網(wǎng)絡(luò)音頻。2.4 客戶端概述音頻數(shù)據(jù)的接收:能夠接受服務(wù)端發(fā)送的音頻信息。音頻數(shù)據(jù)的播放:能夠播放所接收的音頻。頻道的切換:能夠?qū)崿F(xiàn)切換頻道。第3章 服務(wù)器設(shè)計(jì)3.1管道管道是Linux中很重要的一種通信方式,是把一個(gè)進(jìn)程的輸出直接連接到另一個(gè)進(jìn)程的輸入, 常說(shuō)的管道多是指無(wú)名管道,實(shí)際上,管道是一個(gè)固定大小的緩沖區(qū),在Linux 中,管道的實(shí)現(xiàn)并沒(méi)有使用專門的數(shù)據(jù)結(jié)構(gòu),而是借助了文件系統(tǒng)的file結(jié)構(gòu)和VFS的索引節(jié)點(diǎn)inode。通過(guò)將兩個(gè) file 結(jié)構(gòu)指向同一個(gè)臨時(shí)的 VFS 索引

11、節(jié)點(diǎn),而這個(gè) VFS 索引節(jié)點(diǎn)又指向一個(gè)物理頁(yè)面而實(shí)現(xiàn)的。在本設(shè)計(jì)中使用了自己由隊(duì)列實(shí)現(xiàn)的管道,遵循先進(jìn)先出的原則,在該程序中服務(wù)器程序父進(jìn)程把音樂(lè)或者頻道文件發(fā)到管道中,然后其他子進(jìn)程從管道中讀取數(shù)據(jù)發(fā)到網(wǎng)絡(luò)上。3.2令牌桶TBF流控由于本設(shè)計(jì)是在局域網(wǎng)中實(shí)現(xiàn)的,如果不限速的話會(huì)因服務(wù)器發(fā)送數(shù)據(jù)太快而使客戶機(jī)音樂(lè)播放失真,因此加入了令牌桶TBF限速技術(shù)16,限速的原理是根據(jù)mp3音樂(lè)的播放碼率控制服務(wù)器父進(jìn)程單位時(shí)間內(nèi)寫入管道的數(shù)據(jù)流,這樣配合上述的管道就可實(shí)現(xiàn)與mp3音樂(lè)播放速度相同的數(shù)據(jù)流發(fā)送。3.3創(chuàng)建頻道鏈表該軟件服務(wù)器端的核心部分是創(chuàng)建一個(gè)頻道鏈表,在這個(gè)頻道鏈表中存放著和頻道數(shù)一

12、樣多的鏈表節(jié)點(diǎn),每個(gè)鏈表節(jié)點(diǎn)中存放著對(duì)應(yīng)頻道的所有信息,如:頻道號(hào),創(chuàng)建該頻道的線程id,本頻道的描述等,創(chuàng)建頻道鏈表的流程圖如圖4-2所示。 圖4-2 創(chuàng)建頻道鏈表的流程3.4頻道廣播在服務(wù)器程序啟動(dòng)后,父進(jìn)程會(huì)首先創(chuàng)建一個(gè)頻道線程,這個(gè)線程專門負(fù)責(zé)向網(wǎng)絡(luò)上發(fā)送服務(wù)器端的音樂(lè)音樂(lè)列表,每隔0.5秒更新一次,音樂(lè)列表的數(shù)據(jù)包的id為0。3.5數(shù)據(jù)發(fā)送服務(wù)器父進(jìn)程會(huì)創(chuàng)建與頻道數(shù)量相同的數(shù)量的頻道線程,這些頻道線程各自負(fù)責(zé)本頻道音樂(lè)數(shù)據(jù)的發(fā)送,音樂(lè)數(shù)據(jù)包的id與頻道編號(hào)相等,這樣便于客戶機(jī)的選擇接收。發(fā)送流程圖如圖4-3所示。 圖4-3發(fā)送流程圖 第4章 客戶端設(shè)計(jì)4.1選擇頻道在服務(wù)器已經(jīng)運(yùn)行的

13、基礎(chǔ)上打開客服端時(shí),客戶機(jī)會(huì)收到由服務(wù)器發(fā)來(lái)的多播包,內(nèi)容是音樂(lè)頻道列表,音樂(lè)頻道的id是0,所以此時(shí)客戶機(jī)只接收id等于0的數(shù)據(jù)包,該實(shí)現(xiàn)的核心函數(shù)是rcv_channel(),首先用一個(gè)while死循環(huán)來(lái)等待接收音樂(lè)頻道列表,當(dāng)列表收到退出循環(huán),此時(shí)程序應(yīng)該阻塞等待用戶輸入頻道id,當(dāng)用戶輸入頻道id后父進(jìn)程創(chuàng)建一個(gè)子進(jìn)程,這個(gè)子進(jìn)程拿著用戶輸入的頻道id去調(diào)用接收音樂(lè)數(shù)據(jù)接收函數(shù)rcv_music()。當(dāng)切換頻道后,父進(jìn)程會(huì)殺死正在播放音樂(lè)的子進(jìn)程,然后重新創(chuàng)建一個(gè)子進(jìn)程去執(zhí)行rcv_music()函數(shù)播發(fā)新的頻道。接收頻道列表流程圖如圖4-4所示。 圖4-4 客戶機(jī)接收頻道列表流程圖4

14、.2接收數(shù)據(jù)開始父進(jìn)程建立一個(gè)匿名管道用于父子進(jìn)程之間的通信,建立一個(gè)臨時(shí)文件用于當(dāng)作接收音樂(lè)數(shù)據(jù)的緩存文件。接收音樂(lè)數(shù)據(jù)函數(shù)拿到頻道id后,每次接收到來(lái)自服務(wù)器的多播包時(shí)都會(huì)把包中的id與頻道id進(jìn)行比較,如果id相等則說(shuō)明該包是客戶機(jī)所點(diǎn)播的音樂(lè)數(shù)據(jù)包,父進(jìn)程把陸續(xù)收到的音樂(lè)數(shù)據(jù)包都寫到已經(jīng)創(chuàng)建好的緩存文件中,父進(jìn)程再創(chuàng)建一個(gè)子進(jìn)程(以下稱之為小父進(jìn)程)用于音樂(lè)的播放,該小父進(jìn)程再創(chuàng)建一個(gè)子進(jìn)程,小父進(jìn)程從緩存文件中讀取音樂(lè)數(shù)據(jù)放到匿名管道中,子進(jìn)程把管道的標(biāo)準(zhǔn)輸出重定向到標(biāo)準(zhǔn)輸出,此時(shí)在該進(jìn)程中從標(biāo)準(zhǔn)輸入讀數(shù)據(jù)便相當(dāng)于從管道中讀數(shù)據(jù),然后用excel調(diào)用mplayer進(jìn)程去標(biāo)準(zhǔn)輸入讀數(shù)據(jù)

15、進(jìn)行播發(fā)。接收音樂(lè)數(shù)據(jù)包流程圖如圖4-5所示。 圖4-5 接收音樂(lè)數(shù)據(jù)包流程圖第5章 系統(tǒng)調(diào)試5.1 系統(tǒng)的調(diào)試完成系統(tǒng)的軟硬件設(shè)計(jì)后,就可以進(jìn)行系統(tǒng)的調(diào)試了?;诳蛻舳伺c服務(wù)器兩部分,其服務(wù)器較為復(fù)雜,需要redhat安裝交叉編譯環(huán)境。5.2 客戶端調(diào)試客戶端部分的代碼是在redhat中編譯,在終端上運(yùn)行的。頻道選擇函數(shù)static void *choose_thr(void *unused)char ch;while (1) ch = getchar();getchar();if (ch < 0)break;chooseid = ch - '0'pthread_exi

16、t(NULL);inet_pton(AF_INET, client_conf.mgroup, &mreqn.imr_multiaddr);/client_conf.mgroup加入多播組,有發(fā)就可以收接收數(shù)據(jù):while (1) /*收包*/len = recvfrom(sd, msg_list, MSG_LIST_MAX, 0, (void *)&listaddr, &listaddr_len);if (len < sizeof(struct msg_list_st) /fprintf(stderr, "it's too smalln"

17、;);continue;if (msg_list->id != CHNLISTID) fprintf(stderr, "this is not matchn");continue;break;5.3 服務(wù)器調(diào)試服務(wù)器模塊的代碼全部在redhat中編譯和運(yùn)行。static void sock_init(void)struct ip_mreqn reqn;serversd = socket(AF_INET, SOCK_DGRAM, 0);if (serversd < 0) fprintf(stderr, "socket() ERRORn");ex

18、it(1);inet_pton(AF_INET, DEFAULT_MGROUP, &reqn.imr_multiaddr);inet_pton(AF_INET, "0.0.0.0", &reqn.imr_address);reqn.imr_ifindex = if_nametoindex("eth0");if (setsockopt(serversd, IPPROTO_IP, IP_MULTICAST_IF, (void *)&reqn, sizeof(reqn) < 0) fprintf(stderr, "set

19、sockopt() errorn");exit(1);sndaddr.sin_family = AF_INET;sndaddr.sin_port = htons(atoi(DEFAULT_RCVPORT);inet_pton(AF_INET, DEFAULT_MGROUP, &sndaddr.sin_addr);主函數(shù):int main(void)/getoptint err;int i;sock_init();err = mlib_getchnlist(&list, &listsize);if (err) fprintf(stderr, "mlib

20、_getchnlist error");exit(1);thr_list_create(list, listsize);#if 1for (i = 0; i < listsize; i +)thr_channel_create(list + i);#endifwhile (1) pause();第6章 總結(jié)本文提出了一套完整的網(wǎng)絡(luò)音頻點(diǎn)播器的方案,本軟件實(shí)現(xiàn)了基于客戶機(jī)和服務(wù)器模型的網(wǎng)絡(luò)音頻點(diǎn)播系統(tǒng)14,是嵌入式系統(tǒng)在音頻領(lǐng)域中的一個(gè)典型應(yīng)用。本音頻點(diǎn)播系統(tǒng)可以廣泛應(yīng)用在卡拉OK廳、語(yǔ)音教室和公共廣播等多種場(chǎng)所。該軟件分為服務(wù)器和客戶機(jī)兩個(gè)部分,服務(wù)器運(yùn)行在PC機(jī)上,客戶機(jī)運(yùn)行

21、在嵌入式設(shè)備上,服務(wù)器以多播的方式向局域網(wǎng)中所有的客戶機(jī)發(fā)送數(shù)據(jù),客戶機(jī)可以根據(jù)自己的選擇來(lái)決定要接收的數(shù)據(jù)。通過(guò)這次設(shè)計(jì),我理解了嵌入式開發(fā)的流程,以及開發(fā)過(guò)程中需要考慮的關(guān)鍵問(wèn)題,能熟練使用redhat進(jìn)行基本操作。在設(shè)計(jì)過(guò)程中,配置了虛擬機(jī)和WIN7之間的共享文件,安裝了redhat,搭建了socket服務(wù),在網(wǎng)絡(luò)中鏈接,方便調(diào)試。在網(wǎng)上查找各種redhat的配置資料,建立了交叉編譯環(huán)境。通過(guò)以上努力,基本完成了系統(tǒng)設(shè)計(jì)的環(huán)境搭建,并且從中學(xué)習(xí)了許多redhat操作系統(tǒng)的使用方法和系統(tǒng)用到的技術(shù):(1) 學(xué)會(huì)使用makefile文件進(jìn)行自動(dòng)化編譯。(2) 明白了令牌桶基本原理。(3) 學(xué)

22、會(huì)分析wireshark數(shù)據(jù)幀格式。(4) 了解了eclipse界面設(shè)計(jì)過(guò)程。(5) 能夠正確設(shè)置多播組,并讀取管道中發(fā)來(lái)的數(shù)據(jù)。系統(tǒng)中還有很多不足之處需要改進(jìn):(1) 客戶端讀取歌曲信息時(shí),播放時(shí)會(huì)出現(xiàn)斷斷續(xù)續(xù)的情況,流控不是很好。系統(tǒng)使用說(shuō)明書部分代碼說(shuō)明:.H文件Proto.h#ifndef PROTO_H#define PROTO_H#include <site_types.h>#define DEFAULT_RCVPORT "1999"#define DEFAULT_MGROUP"192.168.43.123"#define CHA

23、NNR200#define MINCHNID1#define MAXCHNID(CHANNR + MINCHNID -1)#define CHNLISTID0#define MSG_CHANNEL_MAX(65536 - 20 -8)struct msg_channel_st chnid_t id;/*MUST BETWEEN MIXCHNID AND MAXCHNID*/uint8_t data1;_attribute_(packed);struct msg_listentry_st chnid_t id;/*MUST BETWEEN MIXCHNID AND MAXCHNID*/uint1

24、6_t len;uint8_t desc1;_attribute_(packed);#define MSG_LIST_MAX(65536 - 20 -8)struct msg_list_st chnid_t id;/*MUST BE CHNLISTID*/struct msg_listentry_st entry1;_attribute_(packed);#endifsite_types.h #ifndef SITE_TYPES_H #define SITE_TYPES_H #include <stdint.h> typedef uint8_t chnid_t; #endifCli

25、ent端:Main函數(shù):#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/ip.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <pthread.h>#include <proto.h&g

26、t;#include "client_conf.h"/socket綁定后,加入多播組,父進(jìn)程從管道收菜單包,收頻道包,子進(jìn)程從管道讀。/*getopt *-M 指定多播組 *-P 指定端口 *-p 指定播放器 *-H 顯示幫助 */struct client_conf_st client_conf = .rcvport = DEFAULT_RCVPORT,.mgroup = DEFAULT_MGROUP,.player = DEFAULT_PLAYER;/注意結(jié)構(gòu)體賦值之間用逗號(hào)隔開。定義時(shí)用分號(hào)。static void print_help(void) printf(&q

27、uot;-M 指定多播組n -P 指定端口n -p 指定播放器n -H 顯示幫助n");static int writen(int fd, const char *buf, int len)int ret, pos;pos = 0;while (len > 0) ret = write(fd, buf + pos, len);len -= ret;pos += ret;if (pos <= 0) return -1;return pos;static int chooseid = -1;static void *choose_thr(void *unused)char c

28、h;while (1) ch = getchar();getchar();if (ch < 0)break;chooseid = ch - '0'pthread_exit(NULL);int main(int argc, char *argv)char ch;int sd;pid_t pid;int pfd2;struct sockaddr_in myaddr, listaddr, chnaddr;socklen_t listaddr_len, chnaddr_len;struct ip_mreqn mreqn;struct msg_list_st *msg_list;s

29、truct msg_channel_st *msg_channel;int ret;int len;pthread_t tid;while (1) if (ch = getopt(argc, argv, "M:P:p:H") < 0) break;switch (ch) case 'M':client_conf.mgroup = optarg;break;case 'P':client_conf.rcvport = optarg;break;case 'p':client_conf.player = optarg;bre

30、ak;case 'H':print_help();break;default:break;sd = socket(AF_INET, SOCK_DGRAM, 0);if (sd < 0) perror("socket()");exit(1);inet_pton(AF_INET, client_conf.mgroup, &mreqn.imr_multiaddr);/client_conf.mgroup加入多播組,有發(fā)就可以收inet_pton(AF_INET, "0.0.0.0", &mreqn.imr_address)

31、;mreqn.imr_ifindex = if_nametoindex("eth0");/*if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreqn, sizeof(mreqn) < 0) perror("setsockopt()");exit(1);*/myaddr.sin_family = AF_INET;myaddr.sin_port = htons(atoi(client_conf.rcvport);inet_pton(AF_INET, "192.168.43.123

32、", &myaddr.sin_addr);if (bind(sd, (struct sockaddr *)&myaddr, sizeof(myaddr) < 0) perror("bind()");exit(1);if (pipe(pfd) < 0) perror("pipe()");exit(1);pid = fork();if (pid < 0) perror("fork()");exit(1);if (pid = 0) close(sd);close(pfd1);dup2(pfd0,

33、0);if (pfd0 > 0) close(pfd0);execl("/bin/sh", "sh", "-c", client_conf.player, NULL);perror("execl()");exit(0);close(pfd0);msg_list = malloc(MSG_LIST_MAX);if (msg_list = NULL) fprintf(stderr, "msg_list malloc()n");exit(1);listaddr_len = sizeof(list

34、addr);while (1) /*收包*/len = recvfrom(sd, msg_list, MSG_LIST_MAX, 0, (void *)&listaddr, &listaddr_len);if (len < sizeof(struct msg_list_st) /fprintf(stderr, "it's too smalln");continue;if (msg_list->id != CHNLISTID) fprintf(stderr, "this is not matchn");continue;

35、break;struct msg_listentry_st *pos;for (pos=msg_list->entry; (char *)pos<(char *)(msg_list)+len-1; pos=(void *)(char *)(pos)+(ntohs)(pos->len) printf("channel %d : %sn", pos->id, pos->desc);free(msg_list);/*選擇頻道*/pthread_create(&tid, NULL, choose_thr, NULL);msg_channel =

36、 malloc(MSG_CHANNEL_MAX);if (msg_channel = NULL) fprintf(stderr, "msg_channel malloc()n");exit(1);chnaddr_len = sizeof(chnaddr);int fdt = open("test", O_RDWR | O_CREAT, 0666 );printf("chooseid = %dn", chooseid);while (1) /*收包*/len = recvfrom(sd, msg_channel, MSG_CHANNEL

37、_MAX, 0, (void *)&chnaddr, &chnaddr_len);if (len < sizeof(struct msg_channel_st) fprintf(stderr, "it's too smalln");continue;if (chnaddr.sin_addr.s_addr!=listaddr.sin_addr.s_addr |chnaddr.sin_port!=listaddr.sin_port) fprintf(stderr, "list is not same to channeln");

38、continue;if (msg_channel->id = chooseid) /*寫進(jìn)管道*/ret = write(fdt, msg_channel->data, len-sizeof(chnid_t);ret = writen(pfd1, msg_channel->data, len-sizeof(chnid_t);if (ret < 0) fprintf(stderr, "write pipe errorn");exit(1);printf("channel %d recive %d datan", chooseid, ret); return 0;Server端:Main函數(shù)#include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#i

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論