Arduino以太网客户端服务器通信问题

Arduino Ethernet Client Server communication problem

这是我的代码:

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Ethernet.h>
#include <SPI.h>



bool hands = false;
bool result = true;
char Key;
unsigned int Number=0;
String weight;
String path;
bool alreadyConnected = false; // whether or not the client was connected previously
int cnt=0;


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 2 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask

LiquidCrystal lcd(35, 34, 33, 32, 31, 30);

EthernetServer server(9639); //server port
EthernetClient client;

char keys[4][4] = {
  {'1', '2', '3','A'},
  {'4', '5', '6','B'},
  {'7', '8', '9','C'},
  {'*', '0', '#','D'},
};
byte rowpins[4] = {22, 23, 24, 25};
byte colpins[4] = {26, 27, 28, 29};

Keypad mykeypad = Keypad(makeKeymap(keys), rowpins, colpins, 4, 4);

String readString;

void setup()
{

  lcd.begin(20, 4);


  Ethernet.begin(mac, ip, gateway, subnet);
  
  if (Ethernet.linkStatus() == LinkOFF) {
  lcd.setCursor(0, 0);
  lcd.print("       :Error:       ");
  lcd.setCursor(0, 1);
  lcd.print("Ethernet Cable");
  lcd.setCursor(0, 2);
  lcd.print("Not Connected!");    
    Serial.println("Ethernet cable is not connected.");
    while(true);
  }
   
  Serial.begin(19200);
  Serial1.begin(19200);
  EthernetClient client = server.available();
  
  lcd.setCursor(0, 1);
  lcd.print("    Connecting...    ");
  delay(5000);
  if (client.connect(gateway, 9639))
  {
    client.print("A");
    Serial.println("Connecting MilkyWeigh Server...");
  }
  else
  { lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("1.Check LAN Cable");
    lcd.setCursor(0, 2);
    lcd.print(" --Reset MilkoSol-- ");
    while (true);
  }
  
  server.begin();
  
  while (true) {
    client = server.available();  // wait for a new client:
    if (client)
    {
      while (client.connected())
      {
        if (client.available())
        {
          char b = client.read();
          if (b == 'B')
          {
            lcd.setCursor(0, 2);
            lcd.print("     Connected!     ");
            Serial.println("Successfully Connected!");
            delay(1500);
            hands = true;
            b = "";
          } //if B comes, handshaking done
        } // if client available
      } //while client connected
    } //if (client)
    if (hands == true)
    {
      lcd.clear();
      client.stop();
      break;
    }
  } //while true
  lcd.setCursor(0, 0);
  lcd.print ("Input Code: ");
  lcd.print (Number);
} // void setup

void loop()
{
  while (Key == NO_KEY){
    Key = mykeypad.getKey();
  }
  DetectButtons();
  if (Key == '4')
  {
   SaveToServer();
   delay(200);
   SaveToServer();
  }
    if (Key == '#')
  {   
      if (Number > 0)
      {
        GetName();
      }
      Getweight();
  }
 Key=NO_KEY;
}

void Getweight(){
  while (Serial1.available()>0)
  {
    weight = Serial1.readStringUntil('\r');
    Serial1.flush();
  }
  Serial.print(weight);
}

void SaveToServer()
  {
   if (client.connect(gateway, 9639))
  {
    client.print('@'+String(Number)+','+weight);
    //client.stop();
  }
  else
  { lcd.clear();
    lcd.setCursor(0, 2);
    lcd.print(" Save Error ");
    Serial.println("Try again!");
    Number=0;
    readString="";
  //  weight="";
    alreadyConnected=false;
    return 0;
  }

  server.begin();

      EthernetClient client = server.available(); // Listening for client (i.e. server) response

    if (client)
    {
     if (!alreadyConnected)
     {
      // clear out the input buffer:
      client.flush();
      alreadyConnected = true;
    }
      while (client.connected())
      {
        if (client.available())
        {
          if (client.available()>0)
          {
          char z = client.read();
          if (z == 'K')
          {
            Serial.print("Success: Data Saved!");
            lcd.clear();
            lcd.setCursor(6, 2);
            lcd.print("Success!");
            delay(1500);
            Number=0;
            weight="";
            readString="";
            DisplayResult();
            }
            client.flush();
            client.stop();
          }
        }
      }
    } // if client
  }// SaveToServer

void GetName()
  {
   if (client.connect(gateway, 9639))
  {
    client.print(Number);
    //client.stop();
  }
  else
  { lcd.clear();
    lcd.setCursor(0, 2);
    lcd.print(" Connection Failed! ");
    Serial.println("Connection Failed!");
    Number=0;
    readString="";
  //  weight="";
    alreadyConnected=false;
    return 0;
  }

  server.begin();

      EthernetClient client = server.available(); // Listening for client (i.e. server) response

    if (client)
    {
     if (!alreadyConnected)
     {
      // clear out the input buffer:
      client.flush();
      alreadyConnected = true;
    }
      while (client.connected())
      {
        if (client.available())
        {
          readString="";
          while (client.available()>0)
          {
          //client.readStringUntil('?');
          readString = client.readStringUntil('?');
            client.flush();
            client.stop();
          }
        }
      }
          if (readString == "err")
          {
            lcd.clear();
            lcd.setCursor(0, 2);
            lcd.print("Not found,Try again!");
            Serial.println("Not found,Try again!");
            delay(1500);
            Number=0;
            readString="";
            hands = true;
            DisplayResult();
          }
          else
          {
          lcd.clear();
          DisplayResult();
            Serial.println(readString);
            hands = true;
          }
    } // if client
  }// GetName


void DetectButtons()
{
 // path = path + "DetectButtons";
  //Serial.println(path);
  
  if (Key == '*') //If cancel Button is pressed
  {
    Serial.println ("Button Cancel");
    Number = 0;
    weight = "";
    readString="";
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Input Code:        ");
    lcd.setCursor(0, 1);
    lcd.print("                    ");
    lcd.setCursor(0, 2);
    lcd.print("                    ");
    lcd.setCursor(0, 3);
    lcd.print("                    ");
  }

  if (Key == '1') //If Button 1 is pressed
  { Serial.println ("Button 1");
    if (Number == 0)
      Number = 1;
    else
      Number = (Number * 10) + 1; //Pressed twice
  }
/*
  if (Key == '4') //If Button 4 is pressed
  { Serial.println ("Button 4");
    if (Number == 0)
      Number = 4;
    else
      Number = (Number * 10) + 4; //Pressed twice
  }
*/
  if (Key == '7') //If Button 7 is pressed
  { Serial.println ("Button 7");
    if (Number == 0)
      Number = 7;
    else
      Number = (Number * 10) + 7; //Pressed twice
  }


  if (Key == '0')
  { Serial.println ("Button 0"); //Button 0 is Pressed
    if (Number == 0)
      Number = 0;
    else
      Number = (Number * 10) + 0; //Pressed twice
  }

  if (Key == '2') //Button 2 is Pressed
  { Serial.println ("Button 2");
    if (Number == 0)
      Number = 2;
    else
      Number = (Number * 10) + 2; //Pressed twice
  }

  if (Key == '5')
  { Serial.println ("Button 5");
    if (Number == 0)
      Number = 5;
    else
      Number = (Number * 10) + 5; //Pressed twice
  }

  if (Key == '8')
  { Serial.println ("Button 8");
    if (Number == 0)
      Number = 8;
    else
      Number = (Number * 10) + 8; //Pressed twice
  }

  if (Key == '3')
  { Serial.println ("Button 3");
    if (Number == 0)
      Number = 3;
    else
      Number = (Number * 10) + 3; //Pressed twice
  }

  if (Key == '6')
  { Serial.println ("Button 6");
    if (Number == 0)
      Number = 6;
    else
      Number = (Number * 10) + 6; //Pressed twice
  }

  if (Key == '9')
  { Serial.println ("Button 9");
    if (Number == 0)
      Number = 9;
    else
      Number = (Number * 10) + 9; //Pressed twice
  }
  DisplayResult();
} // end of detect buttons function

void DisplayResult()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print ("Input Code: ");
  lcd.print (Number);
  lcd.setCursor(0, 1);
  lcd.print (readString);
  lcd.setCursor(0, 2);
  lcd.print ("Weight :");
  lcd.print (weight);
  lcd.setCursor(0, 3);
  lcd.print ("*=Cncl,#=Wght,A=Save");
}

问题是当 input_code =111 时第一次按下 '#' 键时,client.read 不知何故错过或跳过来自服务器的响应(名称)并显示空白。但是当我用 input_code = 222 第二次按 '#' 键时,它显示来自服务器的先前响应(名称)。

EthernetClient 可用于连接到远程服务器,如 WebClient 示例中,或者它被 EthernetServer 用作远程客户端的对等点,如 ChatServer 示例中。

如果您同时使用两者,请使用不同的名称。现在您的客户端 'client' 是全局的,从服务器返回的客户端是本地的,但名称相同。您也可以将全局客户端变量设置为本地变量。

变量 alreadyConnected 用于本地客户端和服务器客户端。

您没有停止本地客户端。

您有多余的 while/if (client.available()) 来测试请求(服务器的客户端)。

为什么 while (client.available() > 0) 大约 readStringUntil('?')

EthernetServer 应该在 setup() 中只用 begin 启动一次。