今天給大家介紹的是以太網(wǎng)控制網(wǎng)絡(luò)單片機W7100A的應(yīng)用筆記之如何實現(xiàn)TCP通信。TCP(傳輸控制協(xié)議)是用于控制網(wǎng)絡(luò)間數(shù)據(jù)通信的協(xié)議。作為組成互聯(lián)網(wǎng)的主要協(xié)議之一,更多的詳細內(nèi)容已經(jīng)寫入IETF(互聯(lián)網(wǎng)工程任務(wù)組)的RFC 793中。TCP是運行于IP層上的協(xié)議,它保證了數(shù)據(jù)的有效傳輸并且可以按照數(shù)據(jù)的發(fā)送順序依次進行接收。
本文引用地址:http://butianyuan.cn/article/201611/322031.htm因為W7100A單片機支持傳輸層的TCP協(xié)議,所以用戶不需要做任何整合就可以直接使用TCP/IP協(xié)議。
下面一一給大家做闡述。
1TCP SOCKET
用戶可以在W7100A提供的所有8個SOCKET中使用TCP協(xié)議,但是必須首先創(chuàng)建要使用的SOCKET。在創(chuàng)建SOCKET時,需要用到SOCKET號、協(xié)議、端口號以及標志位。這篇文檔將會介紹什么是TCP協(xié)議,以及在使用TCP協(xié)議時如何將Sn_MR(TCPIP核心中的SOCKET n模式寄存器)設(shè)置為Sn_MR_TCP(0×01)。SOCKET號表示用戶可以選擇從0到7這8個SOCKET中的任意一個使用。端口號表示TCP協(xié)議下用戶指定使用的端口。如果上面需要的這些都已經(jīng)設(shè)定好,那么socket()函數(shù)就可以自行分配創(chuàng)建一個SOCKET。
由于W7100A單片機的TCP協(xié)議支持服務(wù)器模式和客戶端模式,用戶可以任意選擇一個模式實現(xiàn)此應(yīng)用。服務(wù)器模式和客戶端模式的不同見下圖:
<圖1.1> TCP 服務(wù)器和TCP 客戶端
如圖1.1所示,TCP服務(wù)器模式和客戶端模式的過程大致相同。唯一的區(qū)別在于打開SOCKET之后,SOCKET狀態(tài)是監(jiān)聽還是連接。當TCP協(xié)議在服務(wù)器模式下運行時,服務(wù)器處于監(jiān)聽狀態(tài)等待來自客戶端的連接請求。如果TCP協(xié)議運行于客戶端模式下,客戶端將會在連接狀態(tài)下請求連接服務(wù)器。一旦成功建立連接,SOCKET的狀態(tài)將會變成建立(SOCK_ESTABLISHED,0×17)。SOCKET在點對點建立連接之后仍然可以保持連接狀態(tài),從而進行數(shù)據(jù)交換直到SOCKET關(guān)閉。
服務(wù)器模式下的SOCKET循環(huán)周期是由打開、監(jiān)聽、發(fā)送、接收、斷開和關(guān)閉組成??蛻舳四J降腟OCKET循環(huán)周期則是由打開、連接、發(fā)送、接收、斷開和關(guān)閉組成。
1.1打開(OPEN)
無論是在服務(wù)器模式或是客戶端模式下,在創(chuàng)建SOCKET時第一步都是打開SOCKET。利用SOCKET()函數(shù)設(shè)置SOCKET號、協(xié)議、端口號以及標志位來創(chuàng)建一個SOCKETn(取第n-1個SOCKET值)。由于使用的是TCP協(xié)議,需要將協(xié)議設(shè)置為Sn_MR_TCP(0×01)。而端口號的設(shè)置則取決于是在服務(wù)器模式還是客戶端模式下。如果是在服務(wù)器模式下,服務(wù)器會根據(jù)當前用戶所使用的端口來設(shè)置源端口號。但是如果是在客戶端模式下,因為目的端口號正在被使用,最好隨機選擇一個端口號,并每次增加一個數(shù)字,直到SOCKET被連接為止。TCP協(xié)議的標志位表示‘無延時確認標志位’,一般來說,將該位設(shè)置為0。更多關(guān)于協(xié)議類型、標志位等信息,將會在‘TCPIPCore.h’文件下的‘Sn_MR value’中介紹。
在所有的設(shè)置完成之后,通過檢查Sn_SR(n)寄存器來查看SOCKETn的狀態(tài)是否變成SOCK_INIT(0×13)。用戶可以通過getSn_SR(SOCKETn)函數(shù)來完成Sn_SR(N)寄存器的檢查過程。如果SOCKET的狀態(tài)為SOCK_INIT(0×13),表示SOCKET創(chuàng)建成功;如果沒有成功,用戶需要重新創(chuàng)建SOCKET。
例1.1 打開SOCKET
1.2 監(jiān)聽(LISTEN)
監(jiān)聽過程只能在服務(wù)器模式下使用。在SOCKETn創(chuàng)建完成后,為了能與客戶端連接,需要將SOCKET的狀態(tài)從SOCK_INIT(0×13)變成監(jiān)聽。用戶可以直接將Sn_CR(n)寄存器設(shè)置為Sn_CR_LISTEN(0×02)或者可以直接使用’SOCKET.c’文件中的LISTEN()函數(shù)。在變成監(jiān)聽狀態(tài)之后,SOCKET將會改變?yōu)镾OCK_LISTEN(0×14)。然后,SOCKET等待客戶端發(fā)出連接請求。一旦與客戶端建立連接,SOCKET的狀態(tài)將會重新變成SOCK_ESTABLISHED(0×17)。此時,便可以與客戶端之間進行數(shù)據(jù)傳輸。
例 1.2 設(shè)置監(jiān)聽狀態(tài)
1.3 連接(CONNECT)
連接過程發(fā)生在客戶端模式連接到服務(wù)器時。在連接SOCKET時需要用到SOCKET號、目的IP以及目的端口號這些參數(shù)。用戶可以通過CONNECT()函數(shù)進行設(shè)置;一旦成功建立連接,SOCKET的狀態(tài)將會變成SOCK_ESTABLISHED(0×17)。
例 1.3 設(shè)置連接狀態(tài)
1.4 發(fā)送(SEND)
在使用TCP協(xié)議時,與對端的連接在發(fā)送數(shù)據(jù)前就已經(jīng)完成。用戶可以通過SEND()函數(shù)查看設(shè)置的SOCKET號、將要發(fā)送數(shù)據(jù)的地址、數(shù)據(jù)的大小等參數(shù)。將要發(fā)送的數(shù)據(jù)的地址通常由選擇的區(qū)域確定,輸入數(shù)據(jù),并且通過指針設(shè)定區(qū)域。
例1.4 發(fā)送數(shù)據(jù)
1.5 接收(RECEIVE)
接收過程和發(fā)送過程基本相同,唯一不同的是接收(RECEIVE)過程需要檢查的是Sn_RX_RSR(n)。接收過程是指將來自接收緩存器的數(shù)據(jù)移動到用戶數(shù)據(jù)存儲區(qū)。因此,用戶必須在接收之前檢查Sn_RX_RSR(n)的值是否大于0。如果大于0,表示數(shù)據(jù)已經(jīng)保存在接收緩存器中。用戶必須通過getSn_RX_RSR(n)函數(shù)在此過程之前確認數(shù)據(jù)是否被接收。
例1.5 接收數(shù)據(jù)
1.6 斷開(DISCONNECT)
關(guān)閉SOCKET的方法通常有兩種:第一種方法是通過DISCONNECT(n)函數(shù)。DISCONNECT(n)函數(shù)不能用來直接關(guān)閉SOCKET。它先向?qū)Χ税l(fā)送斷開連接請求(FIN數(shù)據(jù)包),然后等待回復(fù)信息(FIN/ACK數(shù)據(jù)包),之后才能將SOCKET的狀態(tài)變成SOCK_CLOSED(0×00),最后關(guān)閉SOCKET。當收到斷開連接請求時,W7100A發(fā)送一個FIN/ACK數(shù)據(jù)包表示允許對端關(guān)閉SOCKET。如果在發(fā)送斷開連接請求之后沒有收到對端的回復(fù),將會發(fā)生TCP超時,SOCKET的狀態(tài)將會變成SOCKET_CLOSED(0×00)。當用戶需要斷開連接時,通過DISCONNECT()函數(shù),選擇合適的SOCKET號,然后發(fā)送斷開連接請求。
評論