在此之前可以阅读前篇博文Arduino-Ethernet库学习笔记(1)。这篇博文是关于该库的简介、调试工具之UDP/TCP网络调试助手NetAssist介绍、Postman介绍以及网络方面的小经验。Arduino-Ethernet库学习笔记(2)学习Arduino-Ethernet库中的Ethernet 类。下面来看IPAddress类和Server类。
2 IPAddress类
IPAddress类可用于本地和远程IP寻址。
2.1 IPAddress()
- 描述
定义一个IP地址。它可以用来声明本地和远程地址。
- 语法
IPAddress(address);
- 参数
address:代表地址的逗号分隔列表(4个字节,例如192, 168, 1, 1)
- 返回值
无
- 例子
#include
#include
// 网络配置。 dns服务器,网关和子网是可选的。
// 板的媒体访问控制(以太网硬件)地址:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// DNS服务器IP
IPAddress dnServer(192, 168, 0, 1);
// 路由器的网关地址
IPAddress gateway(192, 168, 0, 1);
// 子网
IPAddress subnet(255, 255, 255, 0);
//IP地址取决于您的网络
IPAddress ip(192, 168, 0, 2);
void setup() {
Serial.begin(9600);
//初始化以太网设备
Ethernet.begin(mac, ip, dnServer, gateway, subnet);
//打印出IP地址
Serial.print("IP = ");
Serial.println(Ethernet.localIP());
}
void loop() {
}
- 串口打印结果:
IP = 192.168.0.2
3 Server类
服务器类创建服务器,这些服务器可以向连接的客户端(在其他计算机或设备上运行的程序)发送数据或从连接的客户端接收数据。
3.1 EthernetServer()
- 描述
创建一个服务器,以侦听指定端口上的传入连接。
- 语法
Server(port);
- 参数
port:要监听的端口(整数)。
- 返回值
无
- 例子
#include
#include
// 网络配置。网关和子网是可选的。
// 板的媒体访问控制(以太网硬件)地址:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//板的IP地址
byte ip[] = { 192, 168, 1, 177 };
//路由器的网关地址
byte gateway[] = { 192, 168, 1, 1 };
// 子网
byte subnet[] = { 255, 255, 255, 0 };
// telnet默认为端口80
EthernetServer server = EthernetServer(80);
void setup()
{
// 初始化以太网设备
Ethernet.begin(mac, ip, gateway, subnet);
//开始倾听客户
server.begin();
}
void loop()
{
// 如果有传入的客户端连接,将有字节可读取:
EthernetClient client = server.available();
if (client == true) {
//从传入的客户端读取字节并将其写回
// 到连接到服务器的任何客户端:
server.write(client.read());
}
}
3.2 server.begin()
- 描述
告诉服务器开始侦听传入的连接。
- 语法
server.begin()
- 参数
无
- 返回值
无
- 例子
见3.1例子
3.3 server.accept()
- 描述
传统的server.available()函数仅在发送数据后才告诉您新客户端,这使得某些协议(如FTP)无法正确实现。他的意图是程序将使用available()或accept(),但不能同时使用两者。使用available(),客户端连接将继续由EthernetServer管理。您不需要保留客户端对象,因为调用available()会为您提供客户端发送数据的任何方式。使用available(),可以用很少的代码编写简单的服务器。
- 语法
server.accept()
- 参数
无
- 返回值
客户对象。如果没有客户端可读取的数据,则该对象将在if语句中评估为false。 (EthernetClient)。
- 例子
#include
#include
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 177);
// telnet默认为端口23
EthernetServer server(80);
EthernetClient clients[8];
void setup() {
Ethernet.begin(mac, ip);
// 打开串行通信并等待端口打开
Serial.begin(9600);
while (!Serial) {
; // 等待串行端口连接。仅本地USB端口需要
}
// 开始倾听客户
server.begin();
}
void loop() {
// 检查是否有新的客户端连接,并打个招呼(在任何传入数据之前)
EthernetClient newClient = server.accept();
if (newClient) {
for (byte i = 0; i < 8; i++) {
if (!clients[i]) {
newClient.print("Hello, client number: ");
newClient.println(i);
// 一旦我们“accept”,以太网服务器就不再跟踪客户端
// 因此我们必须将其存储到我们的客户列表中
clients[i] = newClient;
break;
}
}
}
// 检查所有客户端的传入数据
for (byte i = 0; i < 8; i++) {
while (clients[i] && clients[i].available() > 0) {
// 从客户端读取传入的数据
Serial.write(clients[i].read());
}
}
// 停止所有断开连接的客户端
for (byte i = 0; i < 8; i++) {
if (clients[i] && !clients[i].connected()) {
clients[i].stop();
}
}
}
结果显示:
3.4 server.available()
- 描述
获取连接到服务器并具有可读取数据的客户端。当返回的客户端对象超出范围时,连接将保留;否则,连接将保留。您可以通过调用client.stop()关闭它。
- 语法
server.available()
- 参数
无
- 返回值
客户对象;如果没有客户端可读取的数据,则该对象将在if语句中评估为false(请参见下面的示例)。
- 例子
#include
#include
// the media access control (ethernet hardware) address for the shield:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//the IP address for the shield:
byte ip[] = { 192, 168, 1, 177 };
// the router's gateway address:
byte gateway[] = { 192, 168, 1, 1 };
// the subnet:
byte subnet[] = { 255, 255,255, 0 };
// telnet defaults to port 80
EthernetServer server = EthernetServer(80);
void setup()
{
// initialize the ethernet device
Ethernet.begin(mac, ip, gateway, subnet);
// start listening for clients
server.begin();
}
void loop()
{
// if an incoming client connects, there will be bytes available to read:
EthernetClient client = server.available();
if (client) {
// read bytes from the incoming client and write them back
// to any clients connected to the server:
server.write(client.read());
}
}
结果显示:
3.5 if(server)
- 描述
指示服务器是否正在侦听新客户端。您可以使用它来检测server.begin()是否成功。它还可以告诉您何时没有更多的套接字可用于侦听更多的客户端,因为已连接了最大数量的客户端。
- 语法
if(server)
- 参数
无
- 返回值
服务器是否正在侦听新客户端(布尔)。
- 例子
#include
#include
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 177);
// telnet defaults to port 80
EthernetServer server = EthernetServer(80);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// initialize the Ethernet device
Ethernet.begin(mac, ip);
// start listening for clients
server.begin();
}
void loop() {
if (server) {
Serial.println("Server is listening");
}
else {
Serial.println("Server is not listening");
}
}
- 串口打印结果:
Server is listening
3.6 server.write()
- 描述
将数据写入连接到服务器的所有客户端。该数据作为一个字节或一系列字节发送。
- 语法
server.write(val)
server.write(buf, len)
- 参数
val:以单个字节(字节或字符)形式发送的值;
buf:以一系列字节(字节或字符)形式发送的数组;
len:缓冲区的长度。
- 返回值
字节
Write()返回写入的字节数。
- 例子
#include
#include
// network configuration. gateway and subnet are optional.
// the media access control (ethernet hardware) address for the shield:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//the IP address for the shield:
byte ip[] = { 192,168, 1, 177 };
// the router's gateway address:
byte gateway[] = { 192, 168, 1, 1 };
// the subnet:
byte subnet[] = { 255, 255, 255, 0 };
// telnet defaults to port 80
EthernetServer server = EthernetServer(80);
void setup()
{
// initialize the ethernet device
Ethernet.begin(mac, ip, gateway, subnet);
// start listening for clients
server.begin();
}
void loop()
{
// if an incoming client connects, there will be bytes available to read:
EthernetClient client = server.available();
if (client == true) {
// read bytes from the incoming client and write them back
// to any clients connected to the server:
server.write(client.read());
}
}
3.7 server.print()
- 描述
将数据打印到连接到服务器的所有客户端。将数字打印为数字序列,每个数字都是一个ASCII字符(例如数字123以三个字符``1'',``2'',``3''发送)。
- 语法
server.print(data)
server.print(data, BASE)
- 参数
data:要打印的数据(char,byte,int,long或string);
BASE(可选):打印数字的基数:BIN(二进制)(基数2),DEC(十进制)(基数10),OCT(八进制)(基数8),HEX(十六进制)(基数16)。
- 返回值
字节
Print()将返回写入的字节数,尽管读取该数字是可选的
3.8 server.println()
- 描述
向连接到服务器的所有客户端打印数据,后跟换行符。将数字打印为数字序列,每个数字都是一个ASCII字符(例如数字123以三个字符``1'',``2'',``3''发送)。
- 语法
server.println()
server.println(data)
server.println(data, BASE)
- 参数
data:要打印的数据(char,byte,int,long或string);
BASE(可选):打印数字的基数:BIN(二进制)(基数2),DEC(十进制)(基数10),OCT(八进制)(基数8),HEX(十六进制)(基数16)。
- 返回值
字节
Println()将返回写入的字节数,尽管读取该数字是可选的。