Byte Banging client.read()

I want to place what might be an HTTP request via Ethernet (UIPEthernet 2.04) into an array that I can then evaluate and respond to. I searched the forum, and found some code examples and have based the following code on those examples. It compiles, but I don’t know if this is the best way or even a working way to do it.

EthernetClient client = server.available();
  int i = 0;
  while (client.connected()){
    if (client.available()){
      char oneByte = client.read();
      if (oneByte == '\n') {
        serverBuffer[i] = oneByte;
        client.stop();
      }
      else if (i < 31){
        serverBuffer[i] = oneByte;
        i++;
      }
      else client.stop();
    }
  }

Your code is missing a bunch of definitions and the setup and loop functions, so no, it won't work.

AWOL:
Your code is missing a bunch of definitions and the setup and loop functions, so no, it won’t work.

#include <UIPEthernet.h>
#include <SPI.h>

byte MacAddress[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte serverBuffer[31];
EthernetServer response(80);

void setup() {
  Ethernet.begin(MacAddress);
  server.begin();
}

void loop() {
  webServer();
  Ethernet.maintain();
}

void webServer(){
  EthernetClient request = response.available();
  int i = 0;
  while (request.connected()){
    if (request.available()){
      char oneByte = request.read();
      if (oneByte == '\n') {
        serverBuffer[i] = oneByte;
        request.stop();
      }
      else if (i < 31){
        serverBuffer[i] = oneByte;
        i++;
      }
      else request.stop();
    }
  }
  // evaluate serverBuffer, clear serverBuffer, send server response
}

I don’t understand the thread title. You aren’t banging any bytes.

I do not understand using a type (byte) in a name (oneByte) when the type is NOT the type if the variable being named. Why not name your char variable oneFloat? That makes as little sense as naming it oneByte.

     if (oneByte == '\n') {
        serverBuffer[i] = oneByte;
        client.stop();
      }

Why do you want to save the carriage return in the buffer?

     else if (i < 31){
        serverBuffer[i] = oneByte;
        i++;
      }

Why do you want to save only non-printing characters in the buffer?

     else client.stop();

Before you receive any carriage returns or non-printing characters, you are likely going to receive header data, causing you to dump the rest of the server response. Doesn’t make sense to me.

EthernetServer response(80);

Seeing response later in the code, I had to go back here to determine what response was. The name, response, for the server instance makes no sense to me.

PaulS:
I don’t understand the thread title. You aren’t banging any bytes.

I do not understand using a type (byte) in a name (oneByte) when the type is NOT the type if the variable being named. Why not name your char variable oneFloat? That makes as little sense as naming it oneByte.

     if (oneByte == '\n') {

serverBuffer[i] = oneByte;
       client.stop();
     }



Why do you want to save the carriage return in the buffer?



else if (i < 31){
       serverBuffer[i] = oneByte;
       i++;
     }



Why do you want to save only non-printing characters in the buffer?



else client.stop();



Before you receive any carriage returns or non-printing characters, you are likely going to receive header data, causing you to dump the rest of the server response. Doesn't make sense to me.

I am trying to index each received byte into and array. “i” is indexing the array, which is 30 or less characters. “oneByte” is a local variable that stores the byte read through the evaluation.
I want to stop indexing bytes at the end of the first line or upon receiving 30 bytes.
naming my server “response” is an error.

PaulS:
Before you receive any carriage returns or non-printing characters, you are likely going to receive header data, causing you to dump the rest of the server response. Doesn't make sense to me.

According to RFC 2616 the first line of the client request should be something like:
"GET World Wide Web Consortium (W3C) HTTP/1.1"
This is the line I want to read into my buffer.

Code: [Select]
else if (i < 31){
serverBuffer = oneByte;

  • i++;*
  • }*
    Why do you want to save only non-printing characters in the buffer?[/quote]
    ?

I am trying to index each received byte into and array. “i” is indexing the array, which is 30 or less characters. “oneByte” is a local variable that stores the byte read through the evaluation.
I want to stop indexing bytes at the end of the first line or upon receiving 30 bytes.

I misread that if statement. I could have sworn that you were comparing oneByte (which is still a crappy name for a character) to 31.

If you are reading characters from the client, why are you storing the characters in a byte array?

AWOL:
?

My question exactly. See my previous response.

PaulS:
If you are reading characters from the client, why are you storing the characters in a byte array?

I need to evaluate "GET" but I can only read a single byte at a time.
If "GET" then I want to evaluate the URI to see if it contains a resource I can provide.
If TRUE then send a response that is the resource.
Else send a response invalid.

Perehama:
I need to evaluate "GET" but I can only read a single byte at a time.
If "GET" then I want to evaluate the URI to see if it contains a resource I can provide.
If TRUE then send a response that is the resource.
Else send a response invalid.

I got that. What I don't understand is why you are saving the chars in a byte array. It makes more sense to me to save bytes in a byte array and chars in a char array. The name oneByte does not make the type a byte.

PaulS:
I got that. What I don't understand is why you are saving the chars in a byte array. It makes more sense to me to save bytes in a byte array and chars in a char array. The name oneByte does not make the type a byte.

I apologize for any naming conventions that are illogical. To me, a char, a byte and uint8_t are all the same, but what I am looking for is to buffer in characters into a character array.

byte, unsigned char and uint8_t are the same.
char (aka signed char) occupies the same amount of memory bits, but is distinct because it is signed.

AWOL:
byte, unsigned char and uint8_t are the same.
char (aka signed char) occupies the same amount of memory bits, but is distinct because it is signed.

My buffer needs to handle http requests and responses. Is "A" == 0b01000001 or 0b11000001? How do other non-arduino systems see signed chars? Do they interpret them as signed chars or unsigned chars?
Do I want a buffer of unsigned chars?

Do I want a buffer of unsigned chars?

If you are reading unsigned chars for the client, yes.

But, since you aren't, no.

Ok, here is the code with clearer naming conventions, and a char array. My basic question still exists. Is this the best method to read the request from the client into and array?

#include <UIPEthernet.h>
#include <SPI.h>

byte MacAddress[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
char serverBuffer[31];
EthernetServer server(80);

void setup() {
  Ethernet.begin(MacAddress);
  server.begin();
}

void loop() {
  webServer();
  Ethernet.maintain();
}

void webServer(){
  EthernetClient client = server.available();
  int index = 0;
  while (client.connected()){
    if (client.available()){
      char character = client.read();
      if (character == '\n') {
        serverBuffer[index] = character;
        client.stop();
      }
      else if (index < 31){
        serverBuffer[index] = character;
        index++;
      }
      else client.stop();
    }
  }
  // evaluate serverBuffer, clear serverBuffer, send server response
}

Is this the best method to read the request from the client into and array?

Close.

Keep in mind that serverBuffer is NOT a string, so don’t plan to pass it to any function (such as strcmp()) that expects a string.

You could make it a string, easily enough. Change its size to 32, and change

        serverBuffer[index] = character;
        index++;

to

        serverBuffer[index++] = character;
        serverBuffer[index] = '\0';

There doesn’t seem much point in storing the carriage return in the array.

Clearing the buffer is a simple matter:

        index = 0;
        serverBuffer[index] = '\0';

PaulS:
Close.

Keep in mind that serverBuffer is NOT a string, so don’t plan to pass it to any function (such as strcmp()) that expects a string.

You could make it a string, easily enough. Change its size to 32, and change

        serverBuffer[index] = character;

index++;



to


serverBuffer[index++] = character;
       serverBuffer[index] = ‘\0’;




There doesn't seem much point in storing the carriage return in the array.


Clearing the buffer is a simple matter:


index = 0;
       serverBuffer[index] = ‘\0’;

To clarify my understanding, you are essentially saying that in order to make it a string for the purpose of strcmp(), I need to have one more index in my array than I do data, where I should place a NULL (’\0’)?
To incorporate your advice, I have written the following code modification.

#include <UIPEthernet.h>
#include <SPI.h>

byte MacAddress[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
char serverBuffer[31];
EthernetServer server(80);

void setup() {
  Ethernet.begin(MacAddress);
  server.begin();
}

void loop() {
  webServer();
  Ethernet.maintain();
}

void webServer() {
  EthernetClient client = server.available();
  int index = 0;
  while (client.connected()) {
    if (client.available()) {
      char character = client.read();
      if (character == '\n') {
        serverBuffer[index] = '\0';
        client.stop();
      }
      else if (index < 30) {
        serverBuffer[index++] = character;
      }
      else {
        serverBuffer[index] = '\0';
        client.stop();
      }
    }
  }
  // evaluate serverBuffer, clear serverBuffer, send server response
}

What happens in my mind is that when a client transmits a request to my hardware, each byte is read, one at a time, and a decision is made,

  1. is the byte a Line Feed character?
    If yes, finish the array with a NULL and stop the client
    If no, 2) have we received less than or equal to 30 bytes?
    If yes, append the array with the new character
    If no, we’ve filled the buffer, save the last spot, so append the NULL and stop the client.
    Now I have a string for the purpose of strcmp()?

PaulS:
Close.

Keep in mind that serverBuffer is NOT a string, so don't plan to pass it to any function (such as strcmp()) that expects a string.

This is exactly what I want to do with it, so I am trying to understand how an char array is not a string and how to make it a string for this purpose.
I have tried to implement the advice given in code and posted it. Does this code implement the changes suggested?