使用Rainbow開發(fā)包的TCP/IP協(xié)議棧,除了可以做TCP客戶端外,還可以作為服務端,接受客戶端連接并進行數據交互。我們先來看看軟件運行的效果:將本文的程序進行編譯、燒寫到Rainbow中,將USB-TTL與電腦連接(這個不是必須的),將網線插入網絡接口,按下Rainbow復位鍵,在串口、網絡通用調試工具中我們將看到:
表明此時Rainbow作為網絡服務器已經啟動,我們在網絡設置區(qū)域選擇作為客戶端、并設置正確的服務器(Rainbow)IP地址、端口,然后點擊“connect”按鈕,此時將會在網絡接收數據區(qū)域顯示一個菜單:
在網絡發(fā)送的輸入區(qū)域輸入0,然后按“send”,板子上的LED便會熄滅;輸入1,然后按“send”,LED又會被點亮。
在軟件包的“Projects\TCP-Server”文件夾包含了本文的完整工程,可以直接編譯、燒寫和調試。這個程序主要展示如何通過TCP向服務器端發(fā)送字符串,看看main.cpp的代碼:
#include "WProgram.h"
#include "Ethernet.h"
#include "EthernetServer.h"
#include "EthernetClient.h"
//定義客戶端通過TCP協(xié)議控制LED亮和滅的管腳
#define LED_PIN PC13
//網絡模塊的MAC地址
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//網絡模塊的IP地址
IPAddress ip(192, 168, 1, 15);
//在6000進行監(jiān)聽
EthernetServer server(6000);
//連接成功后標識設置為true
bool connectFlag = false;
void setup()
{
//初始化Rainbow
boardInit();
//初始化默認串口
Serial.begin();
Serial.println("TCP-Server start...");
//對網絡進行初始化
Ethernet.begin(mac, ip);
//開始進行監(jiān)聽
server.begin();
//使用LED作為指示,客戶端發(fā)送on的時候LED發(fā)光;發(fā)送off的時候LED熄滅
pinMode(LED_PIN, GPIO_Mode_Out_PP);
}
void loop()
{
//取得客戶端socket對象
EthernetClient client = server.available();
//是否和客戶端正確握手
if(client.connected())
{
if(connectFlag)
{
//客戶端是否傳來數據
client.parsePacket();
while(client.available() > 0)
{
//設置超時時間,這個時間主要用于readString()來判斷是否有數據輸入,如果在10ms沒有數據輸入則認為數據輸入完畢,默認是1s
client.setTimeout(10);
String msg = client.readString();
//根據客戶端輸入的數據點亮或關閉LED
if(msg == "1")
digitalWrite(LED_PIN, LOW);
else if(msg == "0")
digitalWrite(LED_PIN, HIGH);
}
}
else
{
//握手成功,輸出操作菜單
connectFlag = true;
String menuStr = "請輸入操作指令:\r\n";
menuStr += "1 - 開燈\r\n";
menuStr += "0 - 關燈\r\n";
client.print(menuStr);
}
}
else if(connectFlag)
{
connectFlag = false;
}
}
int main()
{
setup();
while(1) loop();
}
在Rainbow中對TCP服務端編程和客戶端一樣簡單,按照以下步驟進行:
1、定義TCP服務端對象,在定義對象的時候需要指定監(jiān)聽的端口號:EthernetServer server(6000);
2、開始進行監(jiān)聽:server.begin();
3、獲取客戶端socket對象:EthernetClient client = server.available();
4、通信前需要判斷與客戶端是否成功握手:client.connected(),成功握手返回true
5、與客戶端進行網絡通信。在接收客戶端傳來的數據之前需要調用client.parsePacket(),然后調用client.available()可以返回客戶端發(fā)來的數據量,接下來可以使用EthernetClient提供的各種讀寫方法從網絡上讀寫數據,EthernetClient是Stream的子類,具體讀寫方法參見Stream類