Serial.write () - does not show the last typed characters

Greetings.
I have a problem with writing the received “data” to the serial monitor. My server has a simple socket server in python. Create a skocket connection with a client and send him the data. data are only arbitrary characters

message=chr(48) + chr(52) + chr(51) + chr(53) + chr(57) + chr(51) + chr(57) + chr(35)

The client will connect to the server when the data is uploaded and written

while((size = client.available()) > 0)
          {
            uint8_t* msg = (uint8_t*)malloc(size);
            size = client.read(msg,size);
            Serial.print("START");
            Serial.write(msg,size);
            Serial.println("END");
            free(msg);
          }

I have a problem with the fact that it will not write / show the last character on the serial monitor. Can you please advise me, because I can not help with it.
COMPLET SERVER:

import socket
import sys

from time import sleep
 
HOST = '192.168.1.3'   # Symbolic name, meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print (HOST)
print (PORT)
print ('Socket created')
 
#Bind socket to local host and port
try:
    s.bind((HOST, PORT))
except socket.error as msg:
    print ('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
    sys.exit()
     
print ('Socket bind complete')
 
#Start listening on socket
s.listen(10)
print ('Socket now listening')
 
#now keep talking with the client
while 1:
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print ('Connected with ' + addr[0] + ':' + str(addr[1]))
    message=chr(48) + chr(52) + chr(51) + chr(53) + chr(57) + chr(51) + chr(57) + chr(35)
    conn.send(message)
    sleep(0.5)
     
s.close()

DISPLAY OF SERVER:

192.168.1.3
8888
Socket created
Socket bind complete
Socket now listening
Connected with 192.168.1.118:1025
0435939#

COMPLET CLIENT:

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

EthernetClient client;
signed long next;
boolean state=false;
int size;

void setup(){
  Serial.begin(9600);
  uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05};
  uint8_t ip[4] = {192,168,1,118};
  uint8_t gateway[6] = {192,168,1,1};
  uint8_t subnet[6] = {255,255,255,0};
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.print(" ");
  Serial.print("localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
}

void loop(){
  if (((signed long)(millis() - next)) > 0){
    Serial.println("Client connecting...");
    client.connect(IPAddress(192,168,1,3),8888);
    delay(3000);
    state=client;
    if (client){
      Serial.println("Client connected");
      delay(1000);
      while(client){
        delay(1000);
        next = millis() + 5000;
        if(client.available()==0){
          if (next - millis() < 0){
            goto close;
          }
        }delay(1000);
        while((size = client.available()) > 0)
          {
            uint8_t* msg = (uint8_t*)malloc(size);
            size = client.read(msg,size);
            Serial.print("START");
            Serial.write(msg,size);
            Serial.println("END");
            free(msg);
          }
      }       
    }
  }
  close: 
        Serial.println("Client disconnect");
        client.stop();
}

DISPLAY OF CLIENT to Serial monitor:

localIP: 192.168.1.118
subnetMask: 255.255.255.0
gatewayIP: 255.255.255.0
dnsServerIP: 192.168.1.1
Client connecting...
Client connected
START0435939 END

Not sure this is the issue here but one stumbling block of sockets is that send operates on the network buffers and does not always handle all the bytes you hand over. the call returns when the associated network buffers have been filled and returns how many bytes were actually sent. It is your responsibility to call send again until your message has been completely dealt with.

So I’d give a try to read how many characters have actually been sent and compare with what you wanted to send and possibly send the missing byte(s)

    message=chr(48) + chr(52) + chr(51) + chr(53) + chr(57) + chr(51) + chr(57) + chr(35)
    conn.send(message)

message is NOT a string. How does send() know how many bytes to send?

You are sending binary data to an application that expects ASCII data. What do you expect it to do with the binary data?

You are sending it 8 bytes. It IS printing 8 bytes. Why do you think that it is loosing data?

PaulS:

    message=chr(48) + chr(52) + chr(51) + chr(53) + chr(57) + chr(51) + chr(57) + chr(35)

conn.send(message)



message is NOT a string. How does send() know how many bytes to send?

Paul - this is Python code. chr(x) returns a string of one character whose ASCII code is the integer x. For example, chr(97) returns the string ‘a’.

the + is the concatenation operator → so message is actually indeed a string containing “0435939#” and python figures out the length. what’s weird is that the numbers are correctly received on the other side but not the ‘#’ (chr(35))

```
$> python
Python 2.7.10 (default, Jul 15 2017, 17:16:57)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.
>>> message = chr(48) + chr(52) + chr(51) + chr(53) + chr(57) + chr(51) + chr(57) + chr(35)

print message
0435939#

```

to OP - could you test

 while((size = client.available()) > 0)
          {
            uint8_t* msg = (uint8_t*)malloc(size);
            int r_size = client.read(msg,size);
            if (r_size != size) Serial.println("Did not get the right amount of data");
            Serial.print("START");
            Serial.write(msg, r_size);
            Serial.println("END");
            free(msg);
          }

what's weird is that the numbers are correctly received on the other side but not the '#' (chr(35))

You do NOT know that. You know that 8 characters are sent, and 8 characters are received.

You do not know what the Arduino is doing with the 8th character. THAT is what you are trying to learn.

That python code seems awful. There has GOT to be a better way to define a string.

Yes python is somewhat ugly :slight_smile: but that’s the way you can do that without using String constructors and if you want to use sockets that way

We know what the String holds and supposedly gets sent from the python log

Connected with 192.168.1.118:1025
[color=red]0435939#[/color]

—> there is the # char

We also know what gets printed from the arduino side and seems relatively legit client.read() call

Client connected
START[color=red]0435939 [/color]END

So we see the digits arriving and we see a space (or non printable character represented by space) before the END word the OP had added after sending the number of available bytes to serial using write to get the raw bytes out and not an interpretation which print would have tried if sending each incoming byte (on uint8_t instead of char) (OP doesn’t build a cstring as there isn’t a trailing ‘\0’)

So if I were to debug this i’ll First compare the number of bytes read versus available - just to be sure - then I would print the value of those byte to see what is the last byte i got.would be a good start