亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        Linux環(huán)境下的嵌入式系統(tǒng)網(wǎng)絡(luò)編程應(yīng)用

        2009-04-29 00:00:00江愛珍
        電腦知識(shí)與技術(shù) 2009年15期

        摘要:Linux支持多種類型的套接字地址簇并將其抽象為統(tǒng)一的套接字接口,這一抽象的引入是為了方便互聯(lián)網(wǎng)應(yīng)用程序的編程,也為網(wǎng)絡(luò)應(yīng)用程序之間的數(shù)據(jù)通信提供了便利。該文從socket基本概念入手,介紹了網(wǎng)絡(luò)編程的基本模式及Linux內(nèi)核對(duì)socket的支持。

        關(guān)鍵詞:Linux;嵌入式;網(wǎng)絡(luò)編程

        中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2009)15-3953-02

        Applications of Network Programming in Embedded Linux Systems

        JIANG Ai-zhen

        (Channel 561 in SARFT,NanChang 330046,China)

        Abstract: Linux supports a wide range of types of socket addresses and the abstract cluster as a single socket interface, the introduction of the abstract is for the convenience of Internet application programming, as well as web applications to provide data communications between the convenience. In this paper, starting from the basic concepts of socket, introduced the basic model of network programming and the Linux kernel support for the socket.

        Key words: Linux; Embedded; Network programming

        1 socket概述

        在Linux中的網(wǎng)絡(luò)編程是通過(guò)socket套接字接口來(lái)進(jìn)行的,這一抽象的引入是為了方便聯(lián)網(wǎng)應(yīng)用程序的編程,在UNIX的BSD版本第一次使用了這種接口,因此他也叫做BSD套接字。應(yīng)用程序可以使用這種統(tǒng)一接口收發(fā)網(wǎng)絡(luò)上的數(shù)據(jù),網(wǎng)絡(luò)的socket數(shù)據(jù)傳輸是一種特殊的I/O口,socket也是一種文件描述符。套接字的設(shè)計(jì)符合Linux的習(xí)慣,在理想情況下,應(yīng)將所有可讀寫訪問(wèn)的對(duì)象映射成文件,這樣就可以用普通的文件讀寫操作來(lái)處理這些對(duì)象了,使通信中的收發(fā)可以很容易映射成讀寫操作。在傳輸協(xié)議的上下文中,由這類讀寫操作的對(duì)象就是通信關(guān)系的兩端,他們表示成了套接字。

        BSD套接字是一個(gè)通用接口,它支持不同的網(wǎng)絡(luò)結(jié)構(gòu),同時(shí)也是一個(gè)內(nèi)部進(jìn)程間通信機(jī)制。當(dāng)一個(gè)主機(jī)上同時(shí)有多個(gè)應(yīng)用程序在運(yùn)行,他們使用tcp和udp協(xié)議進(jìn)行通信,則傳輸層協(xié)議收到數(shù)據(jù)后將根據(jù)端口和套接口區(qū)分?jǐn)?shù)據(jù)是傳給哪個(gè)應(yīng)用程序。端口是標(biāo)識(shí)傳輸層與應(yīng)用程序的數(shù)據(jù)接口,每個(gè)端口有一個(gè)16位的標(biāo)識(shí)符。套接口是IP地址與端口號(hào)的組合,用來(lái)標(biāo)識(shí)全網(wǎng)范圍內(nèi)的唯一一個(gè)端口,在tep和udP協(xié)議中用來(lái)標(biāo)識(shí)一個(gè)連接,網(wǎng)絡(luò)應(yīng)用程序之間通過(guò)套接口來(lái)實(shí)現(xiàn)通信。套接字是套接口描述字的簡(jiǎn)稱,是整型數(shù)字,它與文件描述符共用一段數(shù)值空間O_65535。應(yīng)用程序中使用套接字來(lái)調(diào)用套接口,套接字可認(rèn)為是指向套接口的指針,就像文件描述符是指向文件的指針一樣。一個(gè)套接字描述了一個(gè)鏈接的一個(gè)端口,一個(gè)socket端點(diǎn)可以用socket地址來(lái)描述,socket地址結(jié)構(gòu)由正地址,端口和使用協(xié)議組成(TCPorUDP),因此兩個(gè)互聯(lián)的進(jìn)程都要有一個(gè)描述他們之間連結(jié)的套接字。我們也可以把套接字看作為是一種特殊的管道,只是這種管道對(duì)于包含的數(shù)據(jù)量沒有限制。套接字存在于特定的通信域(即地址族)中,只有隸屬于同一地址族的套接字才能建立對(duì)話。Linux支持的協(xié)議族有AF_INET(IPv4協(xié)議)、AF_INET6(IPv6協(xié)議)和AF_UNIX(Unix域協(xié)議)。

        Linux支持多種套接字類型,每種套接字類型對(duì)應(yīng)于創(chuàng)建套接字的應(yīng)用程序所希望的通信服務(wù)類型。同一協(xié)議簇可能提供多種服務(wù)類型,比如TCP/IP協(xié)議族提供的虛電路和數(shù)據(jù)報(bào)就是兩種不同的通信服務(wù)類型。TCP/IP中常用的socket類型共有三種,一種是流式socket(SOCK_STREAM),另一種是數(shù)據(jù)報(bào)式socket(SOCK_DGRAM),還有一種是原始socket(SOCK_RAW)。流式socket是一種面向連結(jié)的socket,對(duì)應(yīng)于面向連接的TCP服務(wù)應(yīng)用。數(shù)據(jù)報(bào)式socket是一種無(wú)連接的socket,對(duì)應(yīng)于無(wú)連接的UDP服務(wù)。原始套接字接口容許對(duì)較低層協(xié)議如IP、ICMP直接訪問(wèn),常用于檢驗(yàn)新的協(xié)議實(shí)現(xiàn)或訪問(wèn)現(xiàn)有服務(wù)中的新設(shè)備。

        2 網(wǎng)絡(luò)編程基本模式

        2.1 客戶機(jī)/服務(wù)器模式

        網(wǎng)絡(luò)編程的基本模式是Client/Serve:模式,該模式的建立基于以下兩點(diǎn):

        1) 非對(duì)等作用;2)通信完全是異步的客戶機(jī)/服務(wù)器模式在操作過(guò)程中采取的是主動(dòng)請(qǐng)示方式,首先服務(wù)器方要先啟動(dòng),并根據(jù)請(qǐng)示提供相應(yīng)服務(wù)。Server端首先調(diào)用socket創(chuàng)建一個(gè)一定類型socket,然后通過(guò)bind函數(shù)將這個(gè)socket綁定到一個(gè)client知道的端口上,接著server調(diào)用Listen函數(shù)設(shè)置傾聽隊(duì)列的長(zhǎng)度,為了接收來(lái)自client端的請(qǐng)求做準(zhǔn)備,然后server調(diào)用accept,開始在所綁定的端口傾聽來(lái)自client端的連接請(qǐng)求。如果socket被設(shè)置成阻塞方式, accept調(diào)用將被阻塞,進(jìn)程被掛起,直到server收到來(lái)自client的請(qǐng)求后,accept才返回。Client端通過(guò)socket調(diào)用創(chuàng)建一個(gè)一定類型的socket(應(yīng)當(dāng)和server的socket類型相同)。然后調(diào)用connect函數(shù)向server所在的主機(jī)發(fā)出連接請(qǐng)求,連接時(shí),需要指定server所在主機(jī)的IP地址和server傾聽的端口號(hào),連接的報(bào)文包含了client端的初始的序號(hào)SYN a和MSS=1460信息(最大數(shù)據(jù)段的大小)。正在傾聽來(lái)自client的連接請(qǐng)求的server收到client的連接請(qǐng)求后,server從accept調(diào)用中返回(通常socket是阻塞方式工作的)。server將會(huì)向client端發(fā)送server端的初始序號(hào)SYN b和對(duì)client端的SYN a的確認(rèn)ACK=a+l,還有本端的最大數(shù)據(jù)MSS當(dāng)client端接收到server端的回應(yīng)時(shí),將發(fā)出對(duì)server請(qǐng)求的ACK=b+1。然后client從connect中返回,返回值是一個(gè)打開的socket的描述符,這個(gè)描述符和文件的描述符類似,程序可以像使用文件的描述符一樣使用它。稍后,在server端收到client端對(duì)其請(qǐng)求的回應(yīng)時(shí),server將從accept調(diào)用返回,返回值也是一個(gè)socket的描述符。

        2.2 面向連接協(xié)議的字節(jié)流套接字編程

        字節(jié)流socket采用的是傳輸控制協(xié)議TCP。TCP提供面向連接的流傳輸,面向連接對(duì)可靠性的保證首先是它在進(jìn)行數(shù)據(jù)傳輸前,必須在信源端和信宿端建立連接。在面向鏈接傳輸?shù)拿恳粋€(gè)報(bào)文都需要接收端確認(rèn),未確認(rèn)的報(bào)文被認(rèn)為是出錯(cuò)報(bào)文。字節(jié)流套接字的服務(wù)器進(jìn)程和客戶進(jìn)程在通信前必須先建立連接,建立連接和通信的步驟如下:

        1) 服務(wù)進(jìn)程首先調(diào)用Socket()創(chuàng)建一個(gè)字節(jié)流套接字,并調(diào)用bind()將服務(wù)器地址捆扎在該套接字上,接著調(diào)用listen()監(jiān)聽連接請(qǐng)求,隨后調(diào)用accept()做好與客戶進(jìn)程建立連接的準(zhǔn)備,無(wú)連接請(qǐng)求時(shí),服務(wù)進(jìn)程被阻塞;

        2) 客戶進(jìn)程調(diào)用Socket()創(chuàng)建字節(jié)流套接字,然后調(diào)用connect()向服務(wù)進(jìn)程發(fā)出連接請(qǐng)求;

        3) 當(dāng)連接請(qǐng)求到來(lái)后,服務(wù)進(jìn)程被喚醒,生成一個(gè)新的字節(jié)流套接字,并用新套接字同客戶進(jìn)程的套接字建立連接,而服務(wù)進(jìn)程最早生成的套接字則繼續(xù)用于監(jiān)聽網(wǎng)絡(luò)上的服務(wù)請(qǐng)求;

        4) 服務(wù)進(jìn)程和客戶進(jìn)程通過(guò)調(diào)用read()和write()交換數(shù)據(jù);

        5) 服務(wù)進(jìn)程和客戶進(jìn)程通過(guò)調(diào)用close()撤消套接字并中斷連接;當(dāng)選擇SOCK STREAM(字節(jié)流)類型的時(shí),sock()系統(tǒng)調(diào)用中的參數(shù)protocol(協(xié)議)總會(huì)選中TCP,而UDP則一直用作SOCK DGRAM類型的傳輸協(xié)議。

        2.3 非連接協(xié)議的數(shù)據(jù)報(bào)套接字編程

        數(shù)據(jù)報(bào)式socket采用的是用戶數(shù)據(jù)報(bào)協(xié)議UDP,它是建立在IP協(xié)議之上的,提供無(wú)連接數(shù)據(jù)報(bào)傳輸,主要應(yīng)用在高可靠性、低延遲的局域網(wǎng)上,它的優(yōu)點(diǎn)是高效率低開銷,不用建立連接和撤銷連接,缺點(diǎn)是不可靠,報(bào)文丟失后需重發(fā)。數(shù)據(jù)套接字的服務(wù)進(jìn)程客戶進(jìn)程通信前不必建立連接,UDP則一直用作SOCKpGRAM類型的傳輸協(xié)議,通信的步驟如下:

        1) 服務(wù)進(jìn)程首先調(diào)用Socket()創(chuàng)建一個(gè)數(shù)據(jù)套接字,并調(diào)用bind將服務(wù)器地址捆扎在該套接字上,然后調(diào)用recvfrom()等待客戶進(jìn)程發(fā)來(lái)的請(qǐng)求;

        2) 客戶進(jìn)程在調(diào)用SocketQ創(chuàng)建一個(gè)數(shù)據(jù)報(bào)套接字后,調(diào)用bindU將客戶機(jī)地址捆扎在此套接字上,接著調(diào)用sendto()向服務(wù)進(jìn)程發(fā)送請(qǐng)求,然后調(diào)用recvfrom()等待服務(wù)進(jìn)程返回該請(qǐng)求的處理結(jié)果;

        3) 服務(wù)進(jìn)程在執(zhí)行客戶進(jìn)程所請(qǐng)求的任務(wù)后,調(diào)用sendto()將處理結(jié)果返回給客戶進(jìn)程;

        4) 服務(wù)進(jìn)程和客戶進(jìn)程通過(guò)調(diào)用close()撤消套接字;

        3 Linux內(nèi)核對(duì)socket的支持

        確切地說(shuō),Linux內(nèi)核只提供了一個(gè)與套接字有關(guān)的系統(tǒng)調(diào)用,應(yīng)用程序的所有套接字調(diào)用都會(huì)映射到這個(gè)系統(tǒng)調(diào)用上。在Linux內(nèi)核中的net/socket.c中定義這個(gè)函數(shù)sys_socketcall(int call,unsigned long *args)。 include/asm/unistd.h中會(huì)指派一個(gè)數(shù)字,該數(shù)字會(huì)和arch/i386/kernel/entry.s中的系統(tǒng)調(diào)用一起添加到表格中。通過(guò)調(diào)用中。all參數(shù)可以說(shuō)明所指向的那個(gè)套接字函數(shù),在include/linux/net.h中定義了可接受的參數(shù)SYS_SOCKET, SYS_IND,SYS_CONNECT, SYS_LISTEN等,在用戶空間的函數(shù)庫(kù)中,帶有特定參數(shù)的sys_socketcall調(diào)用會(huì)映射成某個(gè)獨(dú)立函數(shù),在內(nèi)核中若要選中希望調(diào)用的那個(gè)函數(shù),需要在sys_socketcall函數(shù)中用到一條:witch命令如下所示,而在此之前首先要使用copy_from_user()命令將sys_ socketcall()的函數(shù)復(fù)制到一個(gè)向量中,即ensign long a中。

        if copy_from user(a,args,nargs(call))

        return _EFAULT;

        a0=a[0];

        al=a[1];

        switch(call)

        {

        case

        SYS_SOCKET:

        err=sys_socket(a0,al,a[2]);

        break;

        SYS_BIND:

        err=sys_bind(a0,al,a[2]);

        break;

        SYS_CONNECT:

        err=sys_connect(a0,al,a[2]);

        break;

        為了支持BSD套接字,一個(gè)重要的數(shù)據(jù)結(jié)構(gòu)就是struct socket,它的定義位于

        include/linux/net.h中,其定義如下:

        struct socket

        {

        socket statestate;

        unsigned long flags;

        struct proto_ops *ops;

        structmode *inode;

        structfasync struct *fasync list;

        structfile*file;

        structsock*sk;

        wait queue head t wait;

        shorttype;

        unsigned char passcred;};

        與早期的內(nèi)核相比,socket結(jié)構(gòu)己經(jīng)稍有簡(jiǎn)化。state中存儲(chǔ)的是套接字狀態(tài)可以取值如下(include/linux/net.h):SS_FREE(不忙)、SSes UNCONNECTED(未連通)、SS_ONNECTING(目前正在連接)、SS_ONNECTED(已連通)、SS_ISCONNECTING(目前正在斷開連接)。flags用以同步訪問(wèn),ops指針指向了連通協(xié)議(如tcp或udp)在初始化之后的協(xié)議運(yùn)作。就像Linux中的每個(gè)文件都有一個(gè)mode一樣,每個(gè)BSD套接字也分派了一個(gè)mode o file中存儲(chǔ)了一個(gè)指向該文件結(jié)構(gòu)的指針,這個(gè)結(jié)構(gòu)連接了套接字,因此它可以用與指向套接字。如果有進(jìn)程等待著這個(gè)套接字上的事件,也可以通過(guò)fasync_list找出該進(jìn)程。通過(guò)sk指針可以使用一個(gè)匹配的sock結(jié)構(gòu)。不過(guò),這個(gè)sock結(jié)構(gòu)是由BSD套接字之下、特定于協(xié)議的套接字初始化的,并且連通到這個(gè)指針。字段負(fù)責(zé)根據(jù)用戶空間中的同名套接字調(diào)用存儲(chǔ)第二個(gè)參數(shù),在Linux內(nèi)核include/asm/socket.h中定義了可接受的參數(shù)。

        從上面分析可以看出任何時(shí)候通過(guò)一個(gè)socket來(lái)讀寫數(shù)據(jù)時(shí),都是在使用一個(gè)系統(tǒng)調(diào)用(system_call)這個(gè)調(diào)用(例如read或write)跨越了用戶空間應(yīng)用程序與內(nèi)核的邊界。另外,在進(jìn)入內(nèi)核之前,您的調(diào)用會(huì)通過(guò)C庫(kù)來(lái)進(jìn)入內(nèi)核中的一個(gè)通用函數(shù)system_call()。從system_call()中,這個(gè)調(diào)用會(huì)進(jìn)入文件系統(tǒng)層,內(nèi)核會(huì)在這兒確定正在處理的是哪種類型的設(shè)備。最后,調(diào)用會(huì)進(jìn)入socket層,數(shù)據(jù)就是在這里進(jìn)行讀取或進(jìn)行排隊(duì)從而通過(guò)socket進(jìn)行傳輸?shù)摹?/p>

        4 總結(jié)

        每種網(wǎng)絡(luò)協(xié)議都提供網(wǎng)絡(luò)應(yīng)用開發(fā)接口,TCP/IP協(xié)議的應(yīng)用開發(fā)接口的事實(shí)標(biāo)準(zhǔn)是socket套接口,開發(fā)socket的目的是隱藏網(wǎng)絡(luò)底層的復(fù)雜結(jié)構(gòu)和協(xié)議,使編程人員能夠簡(jiǎn)單抽象的對(duì)網(wǎng)絡(luò)進(jìn)行操作。socket面向客戶機(jī)/服務(wù)器模型,針對(duì)客戶機(jī)/服務(wù)器程序提供不同的socket的系統(tǒng)調(diào)用函數(shù),客戶端隨機(jī)申請(qǐng)一個(gè)socket,操作系統(tǒng)為之分配一個(gè)隨機(jī)socket號(hào);服務(wù)器端擁有全局公認(rèn)的socket號(hào),任何客戶都可以向他發(fā)送連接請(qǐng)求和信息請(qǐng)求。進(jìn)程通信以前,雙方必須各自創(chuàng)建一個(gè)端口,否則是沒有辦法在通信前建立聯(lián)系的,而socket提供了這種進(jìn)程間通信的端口。從網(wǎng)絡(luò)編程的套接字的分析來(lái)看,選擇TCP套接字和選擇UDP套接字編程,在傳輸數(shù)據(jù)時(shí)有著速度、效率和穩(wěn)定性的差別。TCP編程擁有了可靠的數(shù)據(jù)連接,UDP不具有。但是在速度方面,UDP編程確優(yōu)于TCP編程,特別是對(duì)于傳輸短消息?;谶@兩種通信方式優(yōu)缺點(diǎn)的考慮,在后續(xù)編寫IDU控制應(yīng)用軟件時(shí),將UDP套接字用于硬件終端對(duì)外廣播本地IP地址,使局域網(wǎng)內(nèi)客戶端軟件識(shí)別某臺(tái)終端設(shè)備,獲取其MAC地址等硬件信息。將TCP套接字用于在客戶端傳輸用戶數(shù)據(jù),對(duì)硬件終端上的硬件設(shè)備進(jìn)行初始化設(shè)置。

        參考文獻(xiàn):

        [1] Warren W Gay. Linux Socket Programming by Example. Que(R), April 2000.

        [2] Jonathan Corbet,Alessandro Rubini,Greg Kroah-Hartman. Linux Device Drivers 3rd Edition. Reilly Media Inc,2005.

        [3] 孫瓊,嵌入式Linux應(yīng)用程序開發(fā)詳解[M],北京:人民郵電出版社,2006.

        [4] 張斌,高波等,Linux網(wǎng)絡(luò)編程[M],北京:清華大學(xué)出版社,2000.

        [5] Linux技術(shù)叢書委員會(huì).Linux開發(fā)者指南[M].北京:北京希望電子出版社,2008.

        正在播放淫亚洲| 人妻体内射精一区二区三四| 亚洲综合网国产精品一区| 亚洲av无码乱码在线观看牲色| 久久久久成人精品免费播放动漫 | 人妻少妇中文字幕乱码| 日本高清www午色夜高清视频| 精品国产一级毛片大全| 国内自拍偷拍亚洲天堂| 日产一区一区三区区别| 麻豆国产精品va在线观看不卡 | 熟女免费观看一区二区| 国产av综合网站不卡| 日本国产成人国产在线播放| 国产精品国产午夜免费看福利 | 日韩亚洲国产av自拍| 日韩成人精品一区二区三区| 久久熟女少妇一区二区三区| 亚洲开心婷婷中文字幕| 日本又黄又爽gif动态图| 国产视频在线一区二区三区四区| 亚洲天堂av高清在线| 亚洲偷自拍国综合第一页| 免费看男女做羞羞的事网站| 色婷婷综合久久久久中文| 亚洲国产精品午夜电影| 色偷偷亚洲女人的天堂| 国产午夜免费一区二区三区视频 | 国产福利精品一区二区| 亚洲AV无码精品蜜桃| 国产精品很黄很色很爽的网站| 中文字幕人妻日韩精品| 久久亚洲av无码西西人体| 综合精品欧美日韩国产在线| 久久精品日本美女视频| 在线不卡av一区二区| 国精产品一区一区二区三区mba| av无码人妻中文字幕| 一区二区国产在线观看| 白色橄榄树在线阅读免费| 国产高清乱码又大又圆|