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