當前位置:首頁 > 嵌入式 > 嵌入式軟件
[導讀]基于PXA270嵌入式系統(tǒng)的Socket通信設計

1  引言
    PXA270 是Intel 公司的一款基于XScale 架構的高集成度高性能嵌入式處理器,采用ARMv5TE內核,包含了Intel的SpeedStep 技術,優(yōu)化了處理器的功耗,可以動態(tài)調節(jié) CPU 的電壓和頻率來節(jié)省電源的功耗。支持多種嵌入式操作系統(tǒng),如Linux、WinCE、Nucleus、Palm OS、VxWorks等。
    Socket接口是TCP/IP網絡層的API,定義了許多函數和例程,可以用它們來開發(fā)TCP/IP網絡層的應用程序。網絡的Socket數據傳輸是一種特殊的I/O,具有一個類似于打開文件的函數調用Socket(),該函數返回一個整型的Socket描述符,隨后的連接建立、數據傳輸等操作都是通過該Socket實現(xiàn)的。
2 系統(tǒng)設計
    系統(tǒng)的設計分為服務器端和客戶端設計兩部分,服務器端為運行Linux操作系統(tǒng)的PC機,客戶端為PXA270系統(tǒng),在該系統(tǒng)中移植和構建Linux嵌入式操作系統(tǒng),兩者通過Switch交換機進行網絡通信。
2.1 系統(tǒng)工作原理
    在Linux 操作系統(tǒng)中,Socket 屬于文件系統(tǒng)的一部分,網絡通信可以被看作是對文件的讀取。Linux 擁有POSIX 標準庫函數,Socket()、Bind()、Sendto()、Recvfrom()等庫函數可以方便地實現(xiàn)客戶/ 服務器模型中數據的傳送與接收。系統(tǒng)設計主要的目的是完成服務器和客戶端網絡通信的實現(xiàn)。首先啟動宿主機和客戶機的操作系統(tǒng)Linux,然后每個模塊加載網絡設備驅動程序,最后通過TCP/IP協(xié)議建立雙方的通信鏈路,完成Socket通信,詳細情況如圖1所示。
2.2  嵌入式TCP/IP協(xié)議架構
    嵌入式系統(tǒng)作為TCP服務器,在三次握手建立連接的過程中,嵌入式系統(tǒng)作為監(jiān)聽狀態(tài)的服務器,處于LISTEN狀態(tài),等待對方發(fā)起連接。當它接收到SYN數據片,立即發(fā)出SYN+ACK的數據片確認收到對方的SYN,此時變?yōu)镾YN_ RECEIVED狀態(tài)。再接收到對方返回的一個包含ACK的空數據片則三次握手完成,進入ESTABLISHED狀態(tài),最后進行TCP數據通訊。

圖1  系統(tǒng)的原理示意圖
    嵌入式系統(tǒng)建立連接時初始化序列號,然后根據對方發(fā)包中的值來確定序列號,不記憶序列號,不能識別重復報文。嵌入式服務器僅僅在服務器端響應客戶端的請求,接收一個發(fā)送一個確認回答,不考慮失序問題。同時接收到TCP請求后,將存儲于發(fā)送緩沖區(qū)中的數據立即發(fā)送即可,只需一個數據包就能完成,也不需考慮失序問題。
    因為嵌入式系統(tǒng)采用滑動窗口為1的傳輸方式,即發(fā)送一次數據包就等待返回應答,因此當接收不到確認包,就認為自己發(fā)送的包丟失,直接發(fā)送上次發(fā)送的數據。TCP的連接中,當客戶機異常導致連接崩潰時,嵌入式系統(tǒng)發(fā)數據時會被回復復位信號,回到初始狀態(tài)。嵌入式TCP/IP協(xié)議如圖2所示。
3  客戶端/服務器端功能設計
    在TCP/IP網絡中,通信的兩個進程間相互作用的主要模式是客戶/服務器模式,即客戶端向服務器端發(fā)出服務請求,服務器接收到請求后,提供相應的服務??蛻?服務器模式在操作過程中采取的是主動請求方式。

圖2  嵌入式TCP/IP圖解[!--empirenews.page--]
3.1  客戶端程序設計
    客戶端可以向服務器端發(fā)送連接請求,并且客戶端也可以接收到來自服務器端發(fā)送回來的數據。客戶端可以判斷當前自己的工作狀態(tài),如連接的建立,啟動的成功和數據包通信的個數等??蛻舳顺绦蛟O計主要按以下的步驟完成函數的調用:
    ①建立自己的Socket(并驗證建立成功);
    ②啟動連接(并驗證建立成功);
    ③返回連接信息;
    ④接收收到的數據;
    ⑤判斷數據的屬性。
    客戶端程序設計的程序基本流程如圖3所示。

圖3  客戶端程序簡單示意圖
    客戶端打開通信通道,并連接到服務器所在主機的特定端口,向服務器發(fā)送請求報文,等待并接收應答,請求結束后關閉通信通道并終止通信??蛻舳酥饕绦蛉缦拢?br />    Int main(int argc,char *argv[])
    if(argc!=3)
    printf("error!!!please enter the remote IP and PORT please!!! the form like 192.168.0.* 4000n");                           
    mysocket=socket(AF_INET,SOCK_STREAM,0);    //建立一個套接字
    if(mysocket==-1)
    printf("error!!! failed to created the new socket,program end heren");
    printf("OK-- you have successful created a socket named mysocketn");
    return(0);         //socket 建立不成功,回初始位置
    connectcheck=connect(mysocket,(struct sockaddr*)&addr_remote,sizeof(struct sockaddr));
    //調用connect函數連接服務器端
    if(connectcheck==-1)
    printf("error!!!sorry you have failed to connect the remote server!!try again !program end heren");
   // connect不成功回初始位置
    printf("OK-- Now you have successful connect the server,this server IP =%s,and it‘s PORT =%s,now you can communicat with this server!!!!!!!n ",argv[1],argv[2])
    //打印服務器IP地址和端口號
    while(1)
    bzero(gotbuffer,long);
    number=recv(mysocket,gotbuffer,long,0);       
    //調用阻塞函數
    if(number==-1)
    printf("error!!! some thing wrong !let you can not got the data form server,program end heren");
    return(0);
    gotbuffer[number]=‘