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

下載本文檔

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

文檔簡介

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

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

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

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

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

6、ux為用戶提供了完善的、強大的網(wǎng)絡(luò)功能。作為一種網(wǎng)絡(luò)操作系統(tǒng),它在網(wǎng)絡(luò)服務(wù)器上得到了廣泛的應(yīng)用。關(guān)鍵詞: 域名訪問、Linux、網(wǎng)絡(luò)服務(wù)器、服務(wù)器配置目 錄第1章 系統(tǒng)分工- 1 -1.1系統(tǒng)總體功能簡介- 1 -1.2實驗內(nèi)容- 1 -第2章 系統(tǒng)的總體設(shè)計- 2 -2.1技術(shù)支持- 2 -2.2設(shè)計方案- 2 -2.3服務(wù)器概述- 2 -2.4 客戶端概述- 3 -第3章 服務(wù)器設(shè)計- 4 -3.1管道- 4 -3.2令牌桶TBF流控- 4 - 3.3創(chuàng)建頻道鏈表- 4 -3.4頻道廣播- 5 -3.5數(shù)據(jù)發(fā)送- 6 -第4章 客戶端設(shè)計- 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)使用說明書- 13 -部分代碼說明:- 13 -.H文件- 13 -Proto.h- 13 -site_types.h- 14 -Client端:- 14 -Server端:- 19 -評語- 22 -成績:- 22 - 3 -第1章 系統(tǒng)分工1.1系統(tǒng)總體功能簡介 本軟件實現(xiàn)了基于客戶機和服務(wù)器模型的網(wǎng)絡(luò)音頻點播系統(tǒng),是嵌入式系統(tǒng)在音頻領(lǐng)域中的一個典型應(yīng)用。本音頻點播系統(tǒng)可以廣泛應(yīng)用在卡拉OK廳、語音教室和公共廣播等多種場所。該軟件分為服務(wù)器和客戶

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

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

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

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

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

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

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

15、進行播發(fā)。接收音樂數(shù)據(jù)包流程圖如圖4-5所示。 圖4-5 接收音樂數(shù)據(jù)包流程圖第5章 系統(tǒng)調(diào)試5.1 系統(tǒng)的調(diào)試完成系統(tǒng)的軟硬件設(shè)計后,就可以進行系統(tǒng)的調(diào)試了?;诳蛻舳伺c服務(wù)器兩部分,其服務(wù)器較為復(fù)雜,需要redhat安裝交叉編譯環(huán)境。5.2 客戶端調(diào)試客戶端部分的代碼是在redhat中編譯,在終端上運行的。頻道選擇函數(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中編譯和運行。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ò)音頻點播器的方案,本軟件實現(xiàn)了基于客戶機和服務(wù)器模型的網(wǎng)絡(luò)音頻點播系統(tǒng)14,是嵌入式系統(tǒng)在音頻領(lǐng)域中的一個典型應(yīng)用。本音頻點播系統(tǒng)可以廣泛應(yīng)用在卡拉OK廳、語音教室和公共廣播等多種場所。該軟件分為服務(wù)器和客戶機兩個部分,服務(wù)器運行在PC機上,客戶機運行

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

22、會分析wireshark數(shù)據(jù)幀格式。(4) 了解了eclipse界面設(shè)計過程。(5) 能夠正確設(shè)置多播組,并讀取管道中發(fā)來的數(shù)據(jù)。系統(tǒng)中還有很多不足之處需要改進:(1) 客戶端讀取歌曲信息時,播放時會出現(xiàn)斷斷續(xù)續(xù)的情況,流控不是很好。系統(tǒng)使用說明書部分代碼說明:.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綁定后,加入多播組,父進程從管道收菜單包,收頻道包,子進程從管道讀。/*getopt *-M 指定多播組 *-P 指定端口 *-p 指定播放器 *-H 顯示幫助 */struct client_conf_st client_conf = .rcvport = DEFAULT_RCVPORT,.mgroup = DEFAULT_MGROUP,.player = DEFAULT_PLAYER;/注意結(jié)構(gòu)體賦值之間用逗號隔開。定義時用分號。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) /*寫進管道*/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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論