版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> linux TCP服務(wù)器/客戶端通信程序</p><p> 摘要:隨著計(jì)算機(jī)網(wǎng)絡(luò)的不斷發(fā)展,網(wǎng)絡(luò)編程變得越來(lái)越重要,除了簡(jiǎn)單的WEB編程外,還包括利用套接字(Socket)進(jìn)行客戶/服務(wù)器應(yīng)用程序的設(shè)計(jì)。本文先對(duì)與套接字相關(guān)的概念和函數(shù)作了一般性介紹,并提出多線程的編程方法和設(shè)計(jì)流程,也就具體的工程實(shí)例進(jìn)行了流程分析。本文中,對(duì)計(jì)算機(jī)的網(wǎng)絡(luò)模型進(jìn)行了簡(jiǎn)要的分析,并對(duì)TCP的握手模型進(jìn)行了概
2、述;在多線程編程中,本文詳細(xì)分析了多線程的互斥模型,講解了多種線程之間的同步方法,并在程序設(shè)計(jì)中得到體現(xiàn),詳細(xì)講述了Linux中的TCP服務(wù)器/客戶端通信程序,并對(duì)結(jié)果進(jìn)行了驗(yàn)證。</p><p> 關(guān)鍵字:網(wǎng)絡(luò)編程 ;多線程;套接字</p><p><b> 目 錄</b></p><p><b> 緒論1</b>
3、;</p><p><b> 1. 課程背景1</b></p><p> 2. 選題的目的和意義1</p><p> 3. 國(guó)內(nèi)外研究現(xiàn)狀1</p><p> 4. 主要研究?jī)?nèi)容1</p><p> 第1章 需求分析3</p><p> 1.1 設(shè)計(jì)目
4、的3</p><p> 1.2 課題要求3</p><p> 1.3 任務(wù)分析3</p><p> 第2章 環(huán)境搭建4</p><p> 2.1 Ubuntu系統(tǒng)安裝4</p><p> 2.2 開(kāi)發(fā)環(huán)境搭建7</p><p> 2.2.1 NFS環(huán)境介紹7</p
5、><p> 2.2.2 NFS安裝7</p><p> 2.2.3 掛載NFS文件系統(tǒng)7</p><p> 2.2.4 交叉工具安裝8</p><p> 第3章 軟件設(shè)計(jì)9</p><p> 3.1 TCP/IP協(xié)議9</p><p> 3.1.1 網(wǎng)絡(luò)模型9</p&g
6、t;<p> 3.1.2 TCP連接9</p><p> 3.2 多線程編程10</p><p> 3.3 Socket網(wǎng)絡(luò)編程模型12</p><p> 3.3.1 TCP Server編程模型12</p><p> 3.3.2 TCP Client編程模型13</p><p>
7、3.4 程序設(shè)計(jì)13</p><p> 3.4.1 主要內(nèi)容13</p><p> 3.4.2 服務(wù)器端程序設(shè)計(jì)14</p><p> 3.4.3 客戶端程序設(shè)計(jì)16</p><p> 第4章 綜合測(cè)試18</p><p> 4.1 功能測(cè)試18</p><p><b
8、> 第5章 結(jié)論20</b></p><p><b> 參考文獻(xiàn)21</b></p><p> 附錄一 服務(wù)器端程序22</p><p> 附錄二 客戶端程序32</p><p><b> 緒論</b></p><p> Linux經(jīng)歷了
9、20多年的發(fā)展,已經(jīng)成為了一個(gè)功能強(qiáng)大而穩(wěn)定的操作系統(tǒng),在嵌入式系統(tǒng)中也得到廣泛的運(yùn)用,伴隨著物聯(lián)網(wǎng)技術(shù)的普及,網(wǎng)絡(luò)通信在嵌入式系統(tǒng)中扮演著舉足輕重的作用。</p><p><b> 課程背景</b></p><p> 隨著時(shí)代的發(fā)展,網(wǎng)絡(luò)通信在我們的生活中愈來(lái)愈重要,在互聯(lián)網(wǎng)技術(shù)基礎(chǔ)上延伸和擴(kuò)展來(lái)的物聯(lián)網(wǎng)技術(shù),正逐漸改變著我們的世界?;ヂ?lián)網(wǎng)在現(xiàn)實(shí)生活中的應(yīng)用很廣
10、泛,互聯(lián)網(wǎng)給我們的現(xiàn)實(shí)生活帶來(lái)了很大的方便;互聯(lián)網(wǎng)是全球性的,這也就意味著我們能夠打破時(shí)空的界限,通過(guò)互聯(lián)網(wǎng)接觸到世界的每一個(gè)角落;因?yàn)榛ヂ?lián)網(wǎng)的強(qiáng)大力量,這個(gè)時(shí)代的文明發(fā)展得到極大地提高。</p><p><b> 選題的目的和意義</b></p><p> 由于互聯(lián)網(wǎng)超乎尋常的強(qiáng)大力量,改變了這個(gè)時(shí)代的交流方式,改變著人們的生活,未來(lái),我們還將在互聯(lián)網(wǎng)領(lǐng)域得到更
11、多的進(jìn)步,會(huì)影響生活中的方方面面。</p><p><b> 國(guó)內(nèi)外研究現(xiàn)狀</b></p><p> 互聯(lián)網(wǎng)從誕生至今,讓人類文明得到巨大的推動(dòng),伴隨著互聯(lián)網(wǎng)的發(fā)展,各種依托互聯(lián)網(wǎng)的技術(shù)得到迅速發(fā)展,Linux操作系統(tǒng)依據(jù)其優(yōu)良的性能和網(wǎng)絡(luò)功能,在各個(gè)領(lǐng)域都得到極大的普及。21世紀(jì),是互聯(lián)網(wǎng)發(fā)展的有一個(gè)階段,我們國(guó)家已經(jīng)將互聯(lián)網(wǎng)的發(fā)展提升到了戰(zhàn)略高度,明確表示要
12、建成互聯(lián)網(wǎng)強(qiáng)國(guó),我國(guó)到目前為止,已經(jīng)誕生了一大批優(yōu)秀的互聯(lián)網(wǎng)企業(yè),全世界都將在互聯(lián)網(wǎng)的推動(dòng)下,進(jìn)入一個(gè)全新的時(shí)代。</p><p><b> 主要研究?jī)?nèi)容</b></p><p> 設(shè)計(jì)TCP服務(wù)器程序,使用多線程實(shí)現(xiàn)”生產(chǎn)者-消費(fèi)者“模型,建立TCP服務(wù)器,響應(yīng)客戶端請(qǐng)求,發(fā)送客戶端指定的請(qǐng)求數(shù)據(jù)。</p><p><b>
13、主要包括以下內(nèi)容:</b></p><p> 創(chuàng)建線程持續(xù)產(chǎn)生數(shù)據(jù),數(shù)據(jù)包含(學(xué)號(hào),姓名(拼音),年齡,身高,體重,當(dāng)前系統(tǒng)時(shí)間(納秒數(shù))使用gettimeofday(),可使用隊(duì)列/多維數(shù)組存儲(chǔ)數(shù)據(jù);</p><p> 創(chuàng)建TCP服務(wù)器線程,響應(yīng)多個(gè)客戶端的連接,讀取隊(duì)列/數(shù)組,向客戶端發(fā)送指定“學(xué)號(hào)”的數(shù)據(jù)。設(shè)計(jì)TCP服務(wù)器程序;</p><p>
14、; 創(chuàng)建TCP客戶端接收線程,連接服務(wù)器并請(qǐng)求指定“學(xué)號(hào)”的數(shù)據(jù),接收數(shù)據(jù)并存儲(chǔ)在文件中。要求存儲(chǔ)有意義的數(shù)據(jù),由于TCP是基于字節(jié)流的特征,需要做組包處理;</p><p><b> 需求分析</b></p><p><b> 設(shè)計(jì)目的</b></p><p> 通過(guò)對(duì)專業(yè)知識(shí)的熟練運(yùn)用,理解Linux網(wǎng)絡(luò)編程的
15、流程,了解互聯(lián)網(wǎng)的基本架構(gòu),熟悉多線程編程的思想。同時(shí),通過(guò)本課程設(shè)計(jì),可以培養(yǎng)以下能力:</p><p> 獨(dú)立工作能力與創(chuàng)造力;</p><p> 綜合運(yùn)用專業(yè)及基礎(chǔ)知識(shí)的能力;</p><p> 解決實(shí)際工程技術(shù)問(wèn)題的能力;</p><p> 查閱圖書(shū)資料、產(chǎn)品手冊(cè)和各種工具書(shū)的能力;</p><p>
16、 書(shū)寫(xiě)技術(shù)報(bào)告和編制技術(shù)資料的能力。</p><p><b> 課題要求</b></p><p> 使用多線程實(shí)現(xiàn)”生產(chǎn)者-消費(fèi)者“模型,建立TCP服務(wù)器,響應(yīng)客戶端請(qǐng)求,發(fā)送客戶端指定的請(qǐng)求數(shù)據(jù)。</p><p><b> 任務(wù)分析</b></p><p> 創(chuàng)建線程持續(xù)產(chǎn)生數(shù)據(jù),數(shù)據(jù)包含
17、(學(xué)號(hào),姓名(拼音),年齡,身高,體重,當(dāng)前系統(tǒng)時(shí)間(納秒數(shù))使用gettimeofday),可使用隊(duì)列/多維數(shù)組存儲(chǔ)數(shù)據(jù)。理解常用的數(shù)據(jù)結(jié)構(gòu),熟練掌握C編程語(yǔ)言。</p><p> 創(chuàng)建TCP服務(wù)器線程,響應(yīng)多個(gè)客戶端的連接,讀取隊(duì)列/數(shù)組,向客戶端發(fā)送指定“學(xué)號(hào)”的數(shù)據(jù),設(shè)計(jì)TCP服務(wù)器程序,掌握網(wǎng)絡(luò)編程中服務(wù)器端的編程流程。</p><p> 創(chuàng)建TCP客戶端接收線程,連接服務(wù)器
18、并請(qǐng)求指定“學(xué)號(hào)”的數(shù)據(jù),接收數(shù)據(jù)并存儲(chǔ)在文件中。要求存儲(chǔ)有意義的數(shù)據(jù),由于TCP是基于字節(jié)流的特征,需要做組包處理。掌握網(wǎng)絡(luò)編程中客戶端的編程流程。</p><p> 最終的目的是熟練掌握網(wǎng)絡(luò)編程的編程方法,理解常用的數(shù)據(jù)結(jié)構(gòu)的基本思想,掌握編程語(yǔ)言,理解多線程編程在實(shí)際工程中的應(yīng)用。</p><p><b> 環(huán)境搭建</b></p><p
19、> Ubuntu系統(tǒng)安裝</p><p> 考慮到Windows系統(tǒng)的普及程度,本課程實(shí)際將利用虛擬機(jī)來(lái)進(jìn)行開(kāi)發(fā),首先我們需要搭建虛擬機(jī)開(kāi)發(fā)環(huán)境。</p><p><b> 創(chuàng)建虛擬機(jī)</b></p><p><b> 圖2.1.1</b></p><p><b> 選擇操
20、作系統(tǒng)</b></p><p><b> 圖2.1.2</b></p><p> 3.配置處理器和內(nèi)存</p><p><b> 圖2.1.3</b></p><p><b> 圖2.1.4</b></p><p><b>
21、 安裝系統(tǒng)</b></p><p><b> 圖2.1.5</b></p><p><b> 安裝成功界面</b></p><p><b> 圖2.1.6</b></p><p><b> 開(kāi)發(fā)環(huán)境搭建</b></p>
22、<p><b> NFS環(huán)境介紹</b></p><p> NFS(Network File System)即網(wǎng)絡(luò)文件系統(tǒng),是FreeBSD支持的文件系統(tǒng)中的一種,它允許網(wǎng)絡(luò)中的計(jì)算機(jī)之間通過(guò)TCP/IP網(wǎng)絡(luò)共享資源。在NFS的應(yīng)用中,本地NFS的客戶端應(yīng)用可以透明地讀寫(xiě)位于遠(yuǎn)端NFS服務(wù)器上的文件,就像訪問(wèn)本地文件一樣。</p><p><b&g
23、t; NFS安裝</b></p><p> 1.NFS是網(wǎng)絡(luò)文件系統(tǒng)系統(tǒng)的縮寫(xiě),可以用于Linux和Linux之間傳遞文件,實(shí)現(xiàn)數(shù)據(jù)共享。安裝命令如下:</p><p> apt-get install nfs-kernel-server</p><p><b> 2.修改配置文件</b></p><p&
24、gt; 打開(kāi)/etc/exports文件,增加mount -t nfs/NFS (rw,sync,no_root_squash,no_subtree_check)</p><p> 開(kāi)發(fā)板和其他 Linux 主機(jī)可以通過(guò)網(wǎng)絡(luò)訪問(wèn)/NFS 目錄。</p><p><b> 3.啟動(dòng)NFS</b></p><p> sudo service
25、 rpcbind start </p><p> sudo service nfs-kernel-server start</p><p><b> 掛載NFS文件系統(tǒng)</b></p><p> mount -t nfs -o intr,nolock,rsize=1024,wsize=1024 192.168.1.86:/opt/ /mn
26、t</p><p><b> 交叉工具安裝</b></p><p> 1.在/usr/local/下建立交叉編譯器的安裝目錄arm:</p><p> sudo mkdir /usr/local/arm</p><p> 2.將下載的交叉編譯器包解壓到/usr/local/arm目錄下:</p&
27、gt;<p> sudo tar jxvf cross-4.2.2-eabi.tar.bz2 -C /usr/local/arm/ </p><p> 3.解壓成功后,修改PATH環(huán)境變量:</p><p> sudo vim /etc/profile</p><p> 在文件為加入交叉編譯器arm-linux-所在的路徑
28、:</p><p> export PATH=$PATH:/usr/local/arm/4.2.2-eabi/usr/bin</p><p> 4.更新一下配置文件/etc/profile:</p><p> source /etc/profile</p><p><b> 軟件設(shè)計(jì)</b></p>
29、<p><b> TCP/IP協(xié)議</b></p><p><b> 網(wǎng)絡(luò)模型</b></p><p> 圖 3-1-1 網(wǎng)絡(luò)模型</p><p> 如圖3-1-1所示,在TCP/IP協(xié)議中,將互聯(lián)網(wǎng)劃分成為應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、網(wǎng)絡(luò)接口層,其中網(wǎng)絡(luò)接口層的主要功能是提供二進(jìn)制傳輸和介質(zhì)訪問(wèn)的功能;網(wǎng)
30、絡(luò)層負(fù)責(zé)IP尋址和路由,其中要考慮路由算法,擁塞控制等問(wèn)題;傳輸層負(fù)責(zé)應(yīng)用程序之間的連接;</p><p><b> TCP連接</b></p><p> TCP IP一般通過(guò)internet串行線路協(xié)議SLIP或點(diǎn)對(duì)點(diǎn)協(xié)議PPP在串行線上進(jìn)行數(shù)據(jù)傳送。TCP/IP協(xié)議的基本傳輸單位是數(shù)據(jù)包 (datagram)。TCP協(xié)議負(fù)責(zé)把數(shù)據(jù)分成若干個(gè)數(shù)據(jù)包/段,并給每個(gè)
31、數(shù)據(jù)包加上包頭,IP協(xié)議在每個(gè)包頭上再加上接收端主機(jī)地址,這樣數(shù)據(jù)找到自己要去的地方。如果傳輸過(guò)程中出現(xiàn)數(shù)據(jù)丟失、數(shù)據(jù)失真等情況,TCP協(xié)議會(huì)自動(dòng)要求數(shù)據(jù)重新傳輸并重新組包。TCP協(xié)議保證數(shù)據(jù)傳輸?shù)馁|(zhì)量,IP協(xié)議保證數(shù)據(jù)的傳輸。數(shù)據(jù)在傳輸時(shí)每通過(guò)一層就要在數(shù)據(jù)上加個(gè)包頭,其中數(shù)據(jù)供接收端同一層協(xié)議使用,而在接收端每經(jīng)過(guò)一層要把用過(guò)的包頭去掉,這樣來(lái)保證傳輸數(shù)據(jù)的格式完全一致。TCP/IP協(xié)議需要針對(duì)不同的網(wǎng)絡(luò)進(jìn)行不同的設(shè)置,且每個(gè)節(jié)點(diǎn)一
32、般需要一個(gè)“IP地址”、一個(gè)“子網(wǎng)掩碼”、一個(gè)“默認(rèn)網(wǎng)關(guān)”。不過(guò)可以通過(guò)動(dòng)態(tài)主機(jī)配置協(xié)議(DHCP),給客戶端自動(dòng)分配一個(gè)IP地址,這樣避免了出錯(cuò)也簡(jiǎn)化了TCP/IP協(xié)議的設(shè)置。</p><p> 如圖3-1-2所示,TCP是通過(guò)3次握手建立的:</p><p> 客戶端給服務(wù)器發(fā)送SYN(syn = j)包,進(jìn)入SYN_SEND狀態(tài)。</p><p> 服務(wù)
33、器接收到SYNC包,確認(rèn)客戶的SYN(ack = j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(syn = k),把它倆都發(fā)送出去,服務(wù)器進(jìn)入SYN_SEND狀態(tài)。</p><p> 客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送ACK(ack = k+1),客戶端和服務(wù)器都進(jìn)入ESTABLISHED狀態(tài)。此時(shí),連接已經(jīng)建立完畢,可以相互發(fā)送發(fā)送消息。</p><p> 圖 3-1-2 三次
34、握手示意圖</p><p><b> 多線程編程</b></p><p> 進(jìn)程是系統(tǒng)中程序執(zhí)行和資源分配的基本單位。每個(gè)進(jìn)程都擁有自己的數(shù)據(jù)段、代碼段和堆棧段,這就造成了進(jìn)程在進(jìn)行切換等操作時(shí)都需要有比較復(fù)雜的上下文切換等動(dòng)作。為了進(jìn)一步減少處理機(jī)的空轉(zhuǎn)時(shí)間,支持多處理器以及減少上下文切換開(kāi)銷(xiāo),進(jìn)程在演化中出現(xiàn)了另一個(gè)概念——線程。它是進(jìn)程內(nèi)獨(dú)立的一條運(yùn)行路線,
35、處理器調(diào)度的最小單元,也可以稱為輕量級(jí)進(jìn)程。線程可以對(duì)進(jìn)程的內(nèi)存空間和資源進(jìn)行訪問(wèn),并與同一進(jìn)程中的其他線程共享。因此,線程的上下文切換的開(kāi)銷(xiāo)比創(chuàng)建進(jìn)程小很多。</p><p> 同進(jìn)程一樣,線程也將相關(guān)的執(zhí)行狀態(tài)和存儲(chǔ)變量放在線程控制表內(nèi)。一個(gè)進(jìn)程可以有多個(gè)線程,也就是有多個(gè)線程控制表及堆棧寄存器,但卻共享一個(gè)用戶地址空間。要注意的是,由于線程共享了進(jìn)程的資源和地址空間,因此,任何線程對(duì)系統(tǒng)資源的操作都會(huì)給其
36、他線程帶來(lái)影響。由此可知,多線程中的同步是非常重要的問(wèn)題,以下是線程同步用到的一些方法:</p><p><b> 互斥鎖</b></p><p> 互斥鎖是用一種簡(jiǎn)單的加鎖方法來(lái)控制對(duì)共享資源的原子操作。這個(gè)互斥鎖只有兩種狀態(tài),也就是上鎖和解鎖,可以把互斥鎖看作某種意義上的全局變量。在同一時(shí)刻只能有一個(gè)線程掌握某個(gè)互斥鎖,擁有上鎖狀態(tài)的線程能夠?qū)蚕碣Y源進(jìn)行操作
37、。若其他線程希望上鎖一個(gè)已經(jīng)被上鎖的互斥鎖,則該線程就會(huì)掛起,直到上鎖的線程釋放掉互斥鎖為止。可以說(shuō),這把互斥鎖保證讓每個(gè)線程對(duì)共享資源按順序進(jìn)行原子操作。</p><p> 互斥鎖可以分為快速互斥鎖、遞歸互斥鎖和檢錯(cuò)互斥鎖。這三種鎖的區(qū)別主要在于其他未占有互斥鎖的線程在希望得到互斥鎖時(shí)是否需要阻塞等待。快速鎖是指調(diào)用線程會(huì)阻塞直至擁有互斥鎖的線程解鎖為止。遞歸互斥鎖能夠成功地返回,并且增加調(diào)用線程在互斥上加鎖
38、的次數(shù),而檢錯(cuò)互斥鎖則為快速互斥鎖的非阻塞版本,它會(huì)立即返回并返回一個(gè)錯(cuò)誤信息。</p><p> 互斥鎖機(jī)制主要包括下面的基本函數(shù):</p><p> 互斥鎖初始化:pthread_mutex_init()</p><p> 互斥鎖上鎖:pthread_mutex_lock()</p><p> 互斥鎖判斷上鎖:pthread_mu
39、tex_trylock()</p><p> 互斥鎖解鎖:pthread_mutex_unlock()</p><p> 消除互斥鎖:pthread_mutex_destroy()</p><p><b> 信號(hào)量</b></p><p> 信號(hào)量也就是操作系統(tǒng)中所用到的PV原子操作,它廣泛用于進(jìn)程或線程間的同步
40、與互斥。信號(hào)量本質(zhì)上是一個(gè)非負(fù)的整數(shù)計(jì)數(shù)器,它被用來(lái)控制對(duì)公共資源的訪問(wèn)。</p><p> PV原子操作是對(duì)整數(shù)計(jì)數(shù)器信號(hào)量sem的操作。一次P操作使sem減一,而一次V操作使sem加一。進(jìn)程(或線程)根據(jù)信號(hào)量的值來(lái)判斷是否對(duì)公共資源具有訪問(wèn)權(quán)限。當(dāng)信號(hào)量sem的值大于等于零時(shí),該進(jìn)程(或線程)具有公共資源的訪問(wèn)權(quán)限;相反,當(dāng)信號(hào)量sem的值小于零時(shí),該進(jìn)程(或線程)就將阻塞直到信號(hào)量sem的值大于等于0為
41、止。</p><p> 信號(hào)量機(jī)制主要包括下面的基本函數(shù):</p><p> 創(chuàng)建信號(hào)量: sem_init()</p><p> 等待信號(hào)量:sem_wait()和sem_trywait()</p><p> 喚醒進(jìn)程:sem_post()</p><p> 獲取信號(hào)量: sem_getvalue()<
42、;/p><p> 刪除信號(hào)量: sem_destroy()</p><p> Socket網(wǎng)絡(luò)編程模型</p><p> 在Linux中的網(wǎng)絡(luò)編程是通過(guò)socket接口來(lái)進(jìn)行的。socket是一種特殊的I/O接口,它也是一種文件描述符。它是一種常用的進(jìn)程之間通信機(jī)制,通過(guò)它不僅能實(shí)現(xiàn)本地機(jī)器上的進(jìn)程之間的通信,而且通過(guò)網(wǎng)絡(luò)能夠在不同機(jī)器上的進(jìn)程之間進(jìn)行通信。&l
43、t;/p><p> 源IP地址和目的IP地址以及源端口號(hào)和目的端口號(hào)的組合稱為套接字。其用于標(biāo)識(shí)客戶端請(qǐng)求的服務(wù)器和服務(wù),它是網(wǎng)絡(luò)通信過(guò)程中端點(diǎn)的抽象表示,包含進(jìn)行網(wǎng)絡(luò)通信必需的五種信息:連接使用的協(xié)議,本地主機(jī)的IP地址,本地進(jìn)程的協(xié)議端口,遠(yuǎn)地主機(jī)的IP地址,遠(yuǎn)地進(jìn)程的協(xié)議端口。</p><p> TCP Server編程模型</p><p> 圖 3-2-1
44、 Server編程模型</p><p> 進(jìn)行版本協(xié)商(WSAStartup)</p><p> 創(chuàng)建一個(gè)套接字(socket())</p><p> 將套接字設(shè)為監(jiān)聽(tīng)狀態(tài)(listen())</p><p> 接受客戶端的連接請(qǐng)求(accept())</p><p> 發(fā)送或者接收數(shù)據(jù)(send()/rec
45、v())</p><p> 關(guān)閉套接字(close())</p><p> TCP Client編程模型</p><p> 圖 3-2-2 Client編程模型</p><p> 進(jìn)行版本協(xié)商(WSAStartup)</p><p> 創(chuàng)建一個(gè)套接字(socket())</p><p&g
46、t; 連接到服務(wù)器(connect())</p><p> 發(fā)送或者接收函數(shù)(send()/recv())</p><p> 關(guān)閉套接字(close())</p><p><b> 程序設(shè)計(jì)</b></p><p><b> 主要內(nèi)容</b></p><p> 設(shè)
47、計(jì)TCP服務(wù)器程序,使用多線程實(shí)現(xiàn)”生產(chǎn)者-消費(fèi)者“模型,建立TCP服務(wù)器,響應(yīng)客戶端請(qǐng)求,發(fā)送客戶端指定的請(qǐng)求數(shù)據(jù)。</p><p> 1.創(chuàng)建線程持續(xù)產(chǎn)生數(shù)據(jù),數(shù)據(jù)包含(學(xué)號(hào),姓名(拼音),年齡,身高,體重,當(dāng)前系統(tǒng)時(shí)間(納秒數(shù))使用gettimeofday),可使用隊(duì)列/多維數(shù)組存儲(chǔ)數(shù)據(jù)。</p><p> 2.創(chuàng)建TCP服務(wù)器線程,響應(yīng)多個(gè)客戶端的連接,讀取隊(duì)列/數(shù)組,向客戶端
48、發(fā)送指定“學(xué)號(hào)”的數(shù)據(jù)。設(shè)計(jì)TCP服務(wù)器程序。</p><p> 3.創(chuàng)建TCP客戶端接收線程,連接服務(wù)器并請(qǐng)求指定“學(xué)號(hào)”的數(shù)據(jù),接收數(shù)據(jù)并存儲(chǔ)在文件中。要求存儲(chǔ)有意義的數(shù)據(jù),由于TCP是基于字節(jié)流的特征,需要做組包處理</p><p><b> 服務(wù)器端程序設(shè)計(jì)</b></p><p> 以下是服務(wù)器端程序的主函數(shù)部分,在主函數(shù)中,首
49、先創(chuàng)建了一個(gè)新的線程,然后按照網(wǎng)絡(luò)編程模型中服務(wù)器端的編程方法進(jìn)行了編程,詳細(xì)程序設(shè)計(jì)請(qǐng)參考附件1.</p><p> void main(void)</p><p><b> {</b></p><p> /**************子線程相關(guān)*******************/</p><p> pt
50、hread_t reader = -1; //read進(jìn)程的進(jìn)程號(hào)</p><p> pthread_mutex_init(&mutex,NULL); //初始化 互斥鎖</p><p><b> /*初始化數(shù)據(jù)*/</b></p><p> int i = 0;</p><p> for(i=0; i
51、<5; i++)</p><p><b> {</b></p><p> information[i].name = NAME[i];</p><p> information[i].age = AGE[i];</p><p> information[i].number = NUM[i];</p&g
52、t;<p> information[i].high = HIGH[i];</p><p> information[i].weigh = WIGHT[i];</p><p><b> }</b></p><p> /*創(chuàng)建線程,產(chǎn)生數(shù)據(jù)*/</p><p> pthread_create(&a
53、mp;reader,NULL,(void*)&writer_function,NULL);</p><p> /************主線程相關(guān)**********************/</p><p> //創(chuàng)建socket</p><p> nListenSock =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP
54、);</p><p> if(nListenSock<0)</p><p><b> {</b></p><p> printf("create listen socket error\n");</p><p><b> return;</b></p>
55、<p><b> }</b></p><p> //設(shè)置socket選項(xiàng)</p><p> int nValue=1;</p><p> if(setsockopt(nListenSock,SOL_SOCKET,SO_REUSEADDR,(char*)&nValue,sizeof(int))<0)</p&
56、gt;<p><b> {</b></p><p> printf("set option SO_REUSEADDR fail!\n");</p><p> close(nListenSock);</p><p><b> return;</b></p><p&
57、gt;<b> }</b></p><p><b> //綁定</b></p><p> struct sockaddr_in localAddr;</p><p> memset(&localAddr,0x0,sizeof(localAddr));</p><p> localA
58、ddr.sin_family =AF_INET;</p><p> localAddr.sin_addr.s_addr =htonl(INADDR_ANY);</p><p> localAddr.sin_port =htons(10000);</p><p> if(bind(nListenSock,(struct sockaddr*)&localA
59、ddr,sizeof(struct sockaddr))<0)</p><p><b> {</b></p><p> printf("bind liste sock fail!\n");</p><p> close(nListenSock);</p><p><b> re
60、turn;</b></p><p><b> }</b></p><p><b> //監(jiān)聽(tīng)</b></p><p> if(listen(nListenSock,5)<0)</p><p><b> {</b></p><p>
61、; printf("listen error!\n");</p><p> close(nListenSock);</p><p><b> return;</b></p><p><b> }</b></p><p> //創(chuàng)建客戶端的線程</p>&l
62、t;p> int nSrvThreadId =1;</p><p> nThreadFlag =1;</p><p> if(pthread_create((pthread_t*)&nSrvThreadId,NULL,(void*)&serverThreadProc,NULL)<0)</p><p><b> {<
63、/b></p><p> printf("create server thread fail!\n");</p><p> close(nListenSock);</p><p><b> return;</b></p><p><b> }</b></p&g
64、t;<p><b> //等待退出</b></p><p><b> while(1)</b></p><p><b> {</b></p><p> if(pthread_join(nSrvThreadId,NULL)!=0)</p><p><b
65、> {</b></p><p><b> return;</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><
66、b> 客戶端程序設(shè)計(jì)</b></p><p> 以下是客戶端的程序設(shè)計(jì),代碼片段太過(guò)冗長(zhǎng),詳細(xì)的程序設(shè)計(jì)請(qǐng)參考附件2。</p><p> void main(int argc, char** argv)</p><p><b> {</b></p><p><b> //創(chuàng)建套接字&
67、lt;/b></p><p> int sockfd=-1;</p><p> sockfd =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);</p><p> if(sockfd<0)</p><p><b> {</b></p><p>
68、 printf("socket create error\n");</p><p><b> return;</b></p><p><b> }</b></p><p><b> ......</b></p><p><b> //建立
69、連接</b></p><p> while(1) //建立鏈接</p><p><b> {</b></p><p> if(connect(sockfd,</p><p> (struct sockaddr*)&serverAddr,</p><p> size
70、of(serverAddr))==0)</p><p><b> {</b></p><p> printf("connected\n");</p><p><b> break;</b></p><p><b> }</b></p>
71、<p><b> sleep(1);</b></p><p><b> }</b></p><p><b> ......</b></p><p><b> //創(chuàng)建交互進(jìn)程</b></p><p> pthread_t ipt_id;
72、</p><p> if(pthread_create((pthread_t *)&ipt_id,NULL,(void*)&input,NULL)<0)</p><p><b> {</b></p><p> printf("create input thread fail!\n");</p
73、><p> close(ipt_id);</p><p><b> return;</b></p><p><b> }</b></p><p><b> ......</b></p><p><b> }</b></p
74、><p><b> 綜合測(cè)試</b></p><p><b> 功能測(cè)試 </b></p><p> 1.運(yùn)行服務(wù)器端程序,處于監(jiān)聽(tīng)狀態(tài),等待客戶端來(lái)連接,當(dāng)有客戶端連接上,輸出連接的客戶端的信息。</p><p> 圖 4-1-1 服務(wù)器運(yùn)行</p><p> 2.運(yùn)
75、行客戶端程序,等待用戶輸入要從數(shù)據(jù)庫(kù)中讀取的信息編號(hào),當(dāng)用戶輸入要讀取的信息標(biāo)號(hào)的時(shí)候,服務(wù)器響應(yīng)客戶端的請(qǐng)求,回復(fù)信息。</p><p> 圖 4-1-2 客戶端運(yùn)行</p><p> 3.在當(dāng)前目錄下生成一個(gè).txt文件,內(nèi)部包含客戶端請(qǐng)求的信息。</p><p> 圖 4-1-3 生成文件</p><p> 4.打開(kāi)文件,內(nèi)部為
76、請(qǐng)求的信息。</p><p> 圖 4-1-4 文件內(nèi)容</p><p><b> 結(jié)論</b></p><p> 本次課程設(shè)計(jì)的內(nèi)容是基于Linux操作系統(tǒng)的多線程網(wǎng)絡(luò)編程,實(shí)現(xiàn)的功能是“生產(chǎn)者”,“消費(fèi)者”模型,建立TCP服務(wù)器,響應(yīng)客戶端請(qǐng)求,并發(fā)送客戶端請(qǐng)求的數(shù)據(jù)。在程序的設(shè)計(jì)過(guò)程中采用了多線程的編程方式,顯著提高了程序運(yùn)行的效率
77、。</p><p> 客戶端與服務(wù)器通過(guò)TCP方式建立連接,使用的通訊函數(shù)接口為套接字,套接字在網(wǎng)絡(luò)編程中有著舉足輕重的地位。通過(guò)本次課程設(shè)計(jì),我們創(chuàng)建TCP服務(wù)器線程,響應(yīng)多個(gè)客戶端的連接,讀取隊(duì)列/數(shù)組,向客戶端發(fā)送指定“學(xué)號(hào)”的數(shù)據(jù);創(chuàng)建TCP客戶端接收線程,連接服務(wù)器并請(qǐng)求指定“學(xué)號(hào)”的數(shù)據(jù),接收數(shù)據(jù)并存儲(chǔ)在文件中;在實(shí)現(xiàn)的這個(gè)過(guò)程中,利用數(shù)據(jù)結(jié)構(gòu)中的隊(duì)列構(gòu)造了數(shù)據(jù)表,方便程序訪問(wèn),同時(shí),也方便服務(wù)器端
78、對(duì)數(shù)據(jù)的管理。</p><p> 通過(guò)本次課程設(shè)計(jì),掌握了Linux下的編程模式和編程方法,熟悉了Linux的基本操作;同時(shí),掌握了開(kāi)發(fā)環(huán)境的搭建,常用的軟件服務(wù)的安裝,鍛煉了實(shí)際的工程能力;通過(guò)多線程編程方法,理解了線程和進(jìn)程的區(qū)別和聯(lián)系,掌握了創(chuàng)建線程和注銷(xiāo)線程的方法;通過(guò)對(duì)套接字的使用,掌握了在Linux下基于套接字的網(wǎng)絡(luò)編程,理解了Linux下套接字編程在服務(wù)器端和客戶端的編程流程,了解了網(wǎng)絡(luò)模型,提高
79、了解決問(wèn)題的能力。</p><p><b> 參考文獻(xiàn)</b></p><p> 范展源.深度實(shí)踐嵌入式Linux系統(tǒng)移植.北京:機(jī)械工業(yè)出版社,2015.5</p><p> 宋寶華.Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解.北京:機(jī)械工業(yè)出版社,2015.7</p><p> 譚浩強(qiáng).C程序設(shè)計(jì).北京:清華大學(xué)出版社,20
80、10.6</p><p> 陳文智.嵌入式系統(tǒng)設(shè)計(jì)與原理.北京:清華大學(xué)出版社,2011.5</p><p> 宋敬彬.Liunx網(wǎng)絡(luò)編程.北京:清華大學(xué)出版社,2010.6</p><p> 附錄一 服務(wù)器端程序</p><p> /********************************************</p
81、><p> 文件名: server.c</p><p> 文件描述: 嵌入式課程設(shè)計(jì)程序</p><p> 完成日期:2017年9月8日</p><p><b> 作者:陳凱</b></p><p> 聯(lián)系方式:975500487@qq.com</p><p> *
82、*******************************************/</p><p> #include <stdio.h></p><p> #include <sys/types.h></p><p> #include <sys/socket.h></p><p> #in
83、clude <arpa/inet.h></p><p> #include <string.h></p><p> #include <pthread.h> </p><p> #include <stdlib.h></p><p> #include<sys/time.h>
84、</p><p><b> /*函數(shù)申明*/</b></p><p> void writer_function(void);</p><p> void serverThreadProc(void *);</p><p><b> //鏈表結(jié)點(diǎn)結(jié)構(gòu)體</b></p><
85、p> typedef struct _CLIENT_INFO_</p><p><b> {</b></p><p> charszClientIp[16];</p><p> int nClientPort;</p><p> intnClientSock;</p><
86、p> struct_CLIENT_INFO_ *pNext;</p><p> struct_CLIENT_INFO_ *pPre;</p><p> }CLIENT_INFO;</p><p><b> /*數(shù)據(jù)類型*/</b></p><p> typedef struct datatype &l
87、t;/p><p><b> {</b></p><p> unsigned char number;</p><p> unsigned char age;</p><p> unsigned char high;</p><p> unsigned char weigh;</p>
88、;<p> long time;</p><p> char *name;</p><p> }Datatype;</p><p> /****協(xié)議包結(jié)構(gòu)****/</p><p> typedef struct pro_package</p><p><b> {</b&
89、gt;</p><p> char head; //開(kāi)始標(biāo)志為 設(shè)定為0x7E 1</p><p> int lenth; //包的數(shù)據(jù)部分長(zhǎng)度 4</p><p> unsigned char flag; //0 : cmd 1:data 1</p><p> unsigned char sto
90、p; //0 stop 1:send 1</p><p> unsigned char num; //標(biāo)明發(fā)送信息 1</p><p> unsigned char data[200]; //數(shù)據(jù)部分 </p><p> }Pro_package;</p><p><b> /*創(chuàng)建緩存區(qū)*/&
91、lt;/b></p><p> typedef struct queue</p><p><b> {</b></p><p> Datatype buffer[5]; </p><p> int b_tail;</p><p> int b_head;</p>&l
92、t;p><b> }queue; </b></p><p><b> /*初始化隊(duì)列*/</b></p><p> queue Queue = </p><p><b> {</b></p><p> .b_tail = 0,</p><p&
93、gt; .b_head = 0,</p><p><b> };</b></p><p><b> /*數(shù)據(jù)初始化*/</b></p><p> char *NAME[5] = {"wuhao", "chenkai","liumenglin","
94、liujin","liufeng"};</p><p> unsigned char AGE[5] = {20,21,22,23,24};</p><p> unsigned char NUM[5] = {1,2,3,4,5};</p><p> unsigned char HIGH[5] = {175,174,173,175,1
95、65};</p><p> unsigned char WIGHT[5] = {58, 55, 62, 63, 50};</p><p> Datatype information[5];</p><p> /****全局變量***/</p><p> int nListenSock =-1; //server lisen socke
96、t</p><p> int nThreadFlag =0; // thread start/stop flag</p><p> CLIENT_INFO *pClientHead=NULL; //client list header</p><p> struct timeval sys_time;</p><p> pthrea
97、d_mutex_t mutex;</p><p> int buffer_has_item=0;</p><p><b> //主函數(shù)</b></p><p> void main(void)</p><p><b> {</b></p><p> /*******
98、*******子線程相關(guān)*******************/</p><p> pthread_t reader = -1; //read進(jìn)程的進(jìn)程號(hào)</p><p> pthread_mutex_init(&mutex,NULL); //初始化 互斥鎖</p><p><b> /*初始化數(shù)據(jù)*/</b></p>
99、;<p> int i = 0;</p><p> for(i=0; i<5; i++)</p><p><b> {</b></p><p> information[i].name = NAME[i];</p><p> information[i].age = AGE[i];</
100、p><p> information[i].number = NUM[i];</p><p> information[i].high = HIGH[i];</p><p> information[i].weigh = WIGHT[i];</p><p><b> }</b></p><p&g
101、t; /*創(chuàng)建線程,產(chǎn)生數(shù)據(jù)*/</p><p> pthread_create(&reader,NULL,(void*)&writer_function,NULL);</p><p> /************主線程相關(guān)**********************/</p><p> //創(chuàng)建socket</p><p
102、> nListenSock =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);</p><p> if(nListenSock<0)</p><p><b> {</b></p><p> printf("create listen socket error\n");<
103、;/p><p><b> return;</b></p><p><b> }</b></p><p> //設(shè)置socket選項(xiàng)</p><p> int nValue=1;</p><p> if(setsockopt(nListenSock,SOL_SOCKET,
104、</p><p> SO_REUSEADDR,(char*)&nValue,sizeof(int))<0)</p><p><b> {</b></p><p> printf("set option SO_REUSEADDR fail!\n");</p><p> close(
105、nListenSock);</p><p><b> return;</b></p><p><b> }</b></p><p><b> //綁定</b></p><p> struct sockaddr_in localAddr;</p><p
106、> memset(&localAddr,0x0,sizeof(localAddr));</p><p> localAddr.sin_family =AF_INET;</p><p> localAddr.sin_addr.s_addr =htonl(INADDR_ANY);</p><p> localAddr.sin_port =htons
107、(10000);</p><p> if(bind(nListenSock,(struct sockaddr*)&localAddr,sizeof(struct sockaddr))<0)</p><p><b> {</b></p><p> printf("bind liste sock fail!\n&quo
108、t;);</p><p> close(nListenSock);</p><p><b> return;</b></p><p><b> }</b></p><p><b> //監(jiān)聽(tīng)</b></p><p> if(listen(nLi
109、stenSock,5)<0)</p><p><b> {</b></p><p> printf("listen error!\n");</p><p> close(nListenSock);</p><p><b> return;</b></p>
110、<p><b> }</b></p><p> //創(chuàng)建客戶端的線程</p><p> int nSrvThreadId =1;</p><p> nThreadFlag =1;</p><p> if(pthread_create((pthread_t*)&nSrvThreadId,NU
111、LL,(void*)&serverThreadProc,NULL)<0)</p><p><b> {</b></p><p> printf("create server thread fail!\n");</p><p> close(nListenSock);</p><p>
112、;<b> return;</b></p><p><b> }</b></p><p><b> //等待退出</b></p><p><b> while(1)</b></p><p><b> {</b></p&
113、gt;<p> if(pthread_join(nSrvThreadId,NULL)!=0)</p><p><b> {</b></p><p><b> return;</b></p><p><b> }</b></p><p><b>
114、 }</b></p><p><b> }</b></p><p> /*處理客戶端函數(shù)*/</p><p> void serverThreadProc(void *pPram)</p><p><b> {</b></p><p> int nMa
115、xFd;</p><p> fd_set rset,allset;</p><p> struct timeval timeOut={0,20*1000};</p><p> FD_ZERO(&allset);</p><p> FD_SET(nListenSock,&allset);</p><p
116、> nMaxFd =nListenSock;</p><p> CLIENT_INFO *pTcpClient;</p><p> int nSelectR;</p><p> struct sockaddr_in clientAddr;</p><p> CLIENT_INFO *pTempClient;</p>
117、<p> unsigned char ucRcvBuf[100];</p><p> int nAddrSize =sizeof(clientAddr);</p><p> Pro_package package; //定義包結(jié)構(gòu)</p><p> unsigned char send_buffer[200]; //發(fā)送緩存</p&g
118、t;<p> int verify_flag = 0;</p><p> while(1) //while 循環(huán)</p><p><b> {</b></p><p> rset =allset;</p><p> nSelectR =select(nMaxFd+1,&rset,NULL
119、,NULL,&timeOut);</p><p> if(nSelectR==-1) //若發(fā)生錯(cuò)誤</p><p><b> {</b></p><p><b> continue;</b></p><p><b> }</b></p><
120、;p> else if(nSelectR==0) //超時(shí)</p><p><b> {</b></p><p><b> continue;</b></p><p><b> }</b></p><p> if(FD_ISSET(nListenSock,&a
121、mp;rset)) // 檢查nListenSock是否在套接字集合中</p><p><b> {</b></p><p> printf("accept client!\n");</p><p> int nConnectSock =accept(nListenSock,(struct sockaddr*)&a
122、mp;clientAddr,&nAddrSize);</p><p> if(nConnectSock==-1)</p><p><b> {</b></p><p> printf("nConnectSock -1\n");</p><p><b> continue;&l
123、t;/b></p><p><b> }</b></p><p> //保存客戶端的信息</p><p> pTcpClient =(CLIENT_INFO*)malloc(sizeof(CLIENT_INFO));</p><p> pTcpClient->nClientSock =nConnect
124、Sock;</p><p> pTcpClient->nClientPort =ntohs(clientAddr.sin_port);</p><p> strcpy(pTcpClient->szClientIp,inet_ntoa(clientAddr.sin_addr));</p><p> pTcpClient->pNext =NULL
125、;</p><p> pTcpClient->pPre =NULL;</p><p> printf("client connected,ip:%s,port:%d\n",</p><p> pTcpClient->szClientIp,</p><p> pTcpClient->nClientP
126、ort);</p><p> if(pClientHead==NULL)</p><p><b> {</b></p><p> pClientHead= pTcpClient;</p><p><b> }</b></p><p><b> else&l
127、t;/b></p><p><b> {</b></p><p> pTempClient =pClientHead;</p><p> while(pTempClient->pNext!=NULL)</p><p><b> {</b></p><p>
128、 pTempClient =pTempClient->pNext;</p><p><b> }</b></p><p> pTempClient->pNext =pTcpClient;</p><p> pTcpClient->pPre =pTempClient;</p><p><b
129、> }</b></p><p> //update fd set</p><p> FD_SET(nConnectSock,&allset);</p><p> if(nConnectSock>nMaxFd)</p><p><b> {</b></p><p
130、> nMaxFd =nConnectSock;</p><p><b> }</b></p><p><b> }</b></p><p> else //對(duì)客戶端的服務(wù)</p><p><b> {</b></p><p> //f
131、ind the client </p><p> pTcpClient =pClientHead;</p><p> while(pTcpClient!=NULL)</p><p><b> {</b></p><p> int nRcvSock =pTcpClient->nClientSock;</
132、p><p> if(FD_ISSET(nRcvSock,&rset)==0)</p><p><b> {</b></p><p> pTcpClient =pTcpClient->pNext;</p><p><b> continue;</b></p><p
溫馨提示
- 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ù)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 多客戶端嵌入式視頻服務(wù)器的設(shè)計(jì)與實(shí)現(xiàn).pdf
- 嵌入式linux系統(tǒng)郵件客戶端開(kāi)發(fā)
- 網(wǎng)絡(luò)程序設(shè)計(jì)linux服務(wù)器課程設(shè)計(jì)報(bào)告
- 郵件服務(wù)器及客戶端
- 基于linux系統(tǒng)的嵌入式web服務(wù)器設(shè)計(jì)2
- 嵌入式ftp客戶端的設(shè)計(jì)與實(shí)現(xiàn)
- 基于Linux-RT-Linux的嵌入式HTTP服務(wù)器的設(shè)計(jì).pdf
- 嵌入式Linux系統(tǒng)及Web服務(wù)器實(shí)現(xiàn).pdf
- 嵌入式課程設(shè)計(jì)--串口通信
- 嵌入式web服務(wù)器
- tcp_ip課程設(shè)計(jì)---基于套接字的客戶機(jī)服務(wù)器程序設(shè)計(jì)
- 基于Jabber協(xié)議的嵌入式即時(shí)通信客戶端的設(shè)計(jì).pdf
- 嵌入式FTP客戶端的設(shè)計(jì)與實(shí)現(xiàn).doc
- 基于Linux的嵌入式SIP服務(wù)器的研究.pdf
- 基于Linux的嵌入式WEB服務(wù)器的研究.pdf
- 基于嵌入式Linux的網(wǎng)絡(luò)視頻服務(wù)器設(shè)計(jì)與實(shí)現(xiàn).pdf
- vpn服務(wù)器架設(shè)方法+客戶端圖文
- 構(gòu)建嵌入式linux web動(dòng)態(tài)服務(wù)器畢業(yè)論文
- 發(fā)現(xiàn)服務(wù)器已開(kāi)啟的tcp服務(wù)課程設(shè)計(jì)
- 嵌入式linux終端驅(qū)動(dòng)及通信程序開(kāi)發(fā)
評(píng)論
0/150
提交評(píng)論