使用Rainbow开发包的TCP/IP协议栈,除了可以做TCP客户端外,还可以作为服务端,接受客户端连接并进行数据交互。我们先来看看软件运行的效果:将本文的程序进行编译、烧写到Rainbow中,将USB-TTL与电脑连接(这个不是必须的),将网线插入网络接口,按下Rainbow复位键,在串口、网络通用调试工具中我们将看到:
表明此时Rainbow作为网络服务器已经启动,我们在网络设置区域选择作为客户端、并设置正确的服务器(Rainbow)IP地址、端口,然后点击“connect”按钮,此时将会在网络接收数据区域显示一个菜单:
在网络发送的输入区域输入0,然后按“send”,板子上的LED便会熄灭;输入1,然后按“send”,LED又会被点亮。
在软件包的“Projects\TCP-Server”文件夹包含了本文的完整工程,可以直接编译、烧写和调试。这个程序主要展示如何通过TCP向服务器端发送字符串,看看main.cpp的代码:
#include "WProgram.h"
#include "Ethernet.h"
#include "EthernetServer.h"
#include "EthernetClient.h"
//定义客户端通过TCP协议控制LED亮和灭的管脚
#define LED_PIN PC13
//网络模块的MAC地址
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//网络模块的IP地址
IPAddress ip(192, 168, 1, 15);
//在6000进行监听
EthernetServer server(6000);
//连接成功后标识设置为true
bool connectFlag = false;
void setup()
{
//初始化Rainbow
boardInit();
//初始化默认串口
Serial.begin();
Serial.println("TCP-Server start...");
//对网络进行初始化
Ethernet.begin(mac, ip);
//开始进行监听
server.begin();
//使用LED作为指示,客户端发送on的时候LED发光;发送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服务端对象,在定义对象的时候需要指定监听的端口号:EthernetServer server(6000);
2、开始进行监听:server.begin();
3、获取客户端socket对象:EthernetClient client = server.available();
4、通信前需要判断与客户端是否成功握手:client.connected(),成功握手返回true
5、与客户端进行网络通信。在接收客户端传来的数据之前需要调用client.parsePacket(),然后调用client.available()可以返回客户端发来的数据量,接下来可以使用EthernetClient提供的各种读写方法从网络上读写数据,EthernetClient是Stream的子类,具体读写方法参见Stream类