Arduino 以太网和 DHCP 无法与互联网通信
我有一个通过 DHCP 获取 IP 地址的 Web 客户端示例。它成功连接到 IP 地址 192.168.0.1 的路由器,但无法向 google.com
发送 GET HTTP。本质上,我不能允许来自 Arduino 的流量进入互联网。
我有一个连接到 Arduino 的 Linksys/Cisco E2000 路由器。
我的代码如下。
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetDHCP.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x78, 0x0B};
byte ip[] = {192, 168, 0, 125};
byte gateway[] = {192, 168, 0, 1};
byte subnet[] = {255,255,255,0};
byte serverLocal[] = { 192,168,0,1 }; // Google
byte serverExternal[] = { 173,194,33,104 }; // Google
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
Client clientLocal(serverLocal, 80);
Client clientExternal(serverExternal, 80);
const char* ip_to_str(const uint8_t*);
void setup() {
Serial.begin(9600);
Serial.println("Attempting to obtain a DHCP lease...");
// Initiate a DHCP session. The argument is the MAC (hardware) address that
// you want your Ethernet shield to use. This call will block until a DHCP
// lease has been obtained. The request will be periodically resent until
// a lease is granted, but if there is no DHCP server on the network or if
// the server fails to respond, this call will block forever.
// Thus, you can alternatively use polling mode to check whether a DHCP
// lease has been obtained, so that you can react if the server does not
// respond (see the PollingDHCP example).
EthernetDHCP.begin(mac);
// Since we're here, it means that we now have a DHCP lease, so we print
// out some information.
const byte* ipAddr = EthernetDHCP.ipAddress();
const byte* gatewayAddr = EthernetDHCP.gatewayIpAddress();
const byte* dnsAddr = EthernetDHCP.dnsIpAddress();
Serial.println("A DHCP lease has been obtained.");
Serial.print("My IP address is ");
Serial.println(ip_to_str(ipAddr));
Serial.print("Gateway IP address is ");
Serial.println(ip_to_str(gatewayAddr));
Serial.print("DNS IP address is ");
Serial.println(ip_to_str(dnsAddr));
// if you get a connection, report back via serial:
if (clientLocal.connect()) {
Serial.println("connected internally");
// Make a HTTP request:
clientLocal.println("GET /index.html HTTP/1.0");
clientLocal.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed internally");
}
// if you get a connection, report back via serial:
if (clientExternal.connect()) {
Serial.println("connected externally");
// Make a HTTP request:
clientExternal.println("GET /search?q=arduino HTTP/1.0");
clientExternal.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed externally");
}
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (clientLocal.available()) {
char c = clientLocal.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!clientLocal.connected()) {
Serial.println();
Serial.println("disconnecting.");
clientLocal.stop();
}
// if there are incoming bytes available
// from the server, read them and print them:
if (clientLocal.available()) {
char c = clientLocal.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!clientExternal.connected()) {
Serial.println();
Serial.println("disconnecting.");
clientExternal.stop();
// do nothing forevermore:
for(;;)
;
}
}
// Just a utility function to nicely format an IP address.
const char* ip_to_str(const uint8_t* ipAddr)
{
static char buf[16];
sprintf(buf, "%d.%d.%d.%d\0", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]);
return buf;
}
I have this web client example that gets an IP address via DHCP. It connects to my router at IP address 192.168.0.1 successfully, but then it fails to send a GET HTTP to google.com
. Essentially, I cannot allow the traffic from Arduino to go out into the Internet.
I have a Linksys/Cisco E2000 router connected to the Arduino.
My code is below.
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetDHCP.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x78, 0x0B};
byte ip[] = {192, 168, 0, 125};
byte gateway[] = {192, 168, 0, 1};
byte subnet[] = {255,255,255,0};
byte serverLocal[] = { 192,168,0,1 }; // Google
byte serverExternal[] = { 173,194,33,104 }; // Google
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
Client clientLocal(serverLocal, 80);
Client clientExternal(serverExternal, 80);
const char* ip_to_str(const uint8_t*);
void setup() {
Serial.begin(9600);
Serial.println("Attempting to obtain a DHCP lease...");
// Initiate a DHCP session. The argument is the MAC (hardware) address that
// you want your Ethernet shield to use. This call will block until a DHCP
// lease has been obtained. The request will be periodically resent until
// a lease is granted, but if there is no DHCP server on the network or if
// the server fails to respond, this call will block forever.
// Thus, you can alternatively use polling mode to check whether a DHCP
// lease has been obtained, so that you can react if the server does not
// respond (see the PollingDHCP example).
EthernetDHCP.begin(mac);
// Since we're here, it means that we now have a DHCP lease, so we print
// out some information.
const byte* ipAddr = EthernetDHCP.ipAddress();
const byte* gatewayAddr = EthernetDHCP.gatewayIpAddress();
const byte* dnsAddr = EthernetDHCP.dnsIpAddress();
Serial.println("A DHCP lease has been obtained.");
Serial.print("My IP address is ");
Serial.println(ip_to_str(ipAddr));
Serial.print("Gateway IP address is ");
Serial.println(ip_to_str(gatewayAddr));
Serial.print("DNS IP address is ");
Serial.println(ip_to_str(dnsAddr));
// if you get a connection, report back via serial:
if (clientLocal.connect()) {
Serial.println("connected internally");
// Make a HTTP request:
clientLocal.println("GET /index.html HTTP/1.0");
clientLocal.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed internally");
}
// if you get a connection, report back via serial:
if (clientExternal.connect()) {
Serial.println("connected externally");
// Make a HTTP request:
clientExternal.println("GET /search?q=arduino HTTP/1.0");
clientExternal.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed externally");
}
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (clientLocal.available()) {
char c = clientLocal.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!clientLocal.connected()) {
Serial.println();
Serial.println("disconnecting.");
clientLocal.stop();
}
// if there are incoming bytes available
// from the server, read them and print them:
if (clientLocal.available()) {
char c = clientLocal.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!clientExternal.connected()) {
Serial.println();
Serial.println("disconnecting.");
clientExternal.stop();
// do nothing forevermore:
for(;;)
;
}
}
// Just a utility function to nicely format an IP address.
const char* ip_to_str(const uint8_t* ipAddr)
{
static char buf[16];
sprintf(buf, "%d.%d.%d.%d\0", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]);
return buf;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个工作代码示例(也许您将其用作来源?)。我能看到的唯一区别是以下几行:
就在该行之前:
我怀疑附加的
Serial.begin()
有任何效果,但delay()
可能 是必需的(尽管可能性很小......)Here's an example of working code (maybe you used this as a source?). The only differences I could see are the lines:
just before the line:
I doubt the additional
Serial.begin()
has any effect but thedelay()
may be required (although it's a long shot...)