Lost packets

Hey,

I am using Arduino due as client with MVC as a server that runs on my local PC.
The arduino client is polling for actions from the server every 3 seconds.

The communication works fine most of the times, but once every 10-15 seconds the client can’t get a response from the server. I know that the server is getting all the requests from the arduino(writing a log in server), and also sends back a response (with using wireshark). When a message is not received in the arduino-client, it says on the wireshark:

62148 10:37:26.515258000 192.168.1.251 192.168.1.48 HTTP 254 [TCP Retransmission] HTTP/1.1 200 OK (text/html)

and then:

62186 10:37:32.378177000 192.168.1.48 192.168.1.251 TCP 60 [TCP Dup ACK 62184#1] 49628→80 [ACK] Seq=253 Ack=1 Win=2048 Len=0
62188 10:37:32.579896000 192.168.1.48 192.168.1.251 TCP 60 [TCP Spurious Retransmission] 49628→80 [FIN, ACK] Seq=252 Ack=1 Win=2048 Len=0
62189 10:37:32.579919000 192.168.1.251 192.168.1.48 TCP 54 [TCP Dup ACK 62185#1] 80→49628 [ACK] Seq=692 Ack=253 Win=64050 Len=0
62190 10:37:32.580089000 192.168.1.48 192.168.1.251 TCP 60 [TCP Dup ACK 62188#1] 49628→80 [ACK] Seq=253 Ack=1 Win=2048 Len=0
62192 10:37:32.984329000 192.168.1.48 192.168.1.251 TCP 60 [TCP Spurious Retransmission] 49628→80 [FIN, ACK] Seq=252 Ack=1 Win=2048 Len=0
62193 10:37:32.984365000 192.168.1.251 192.168.1.48 TCP 54 [TCP Dup ACK 62185#2] 80→49628 [ACK] Seq=692 Ack=253 Win=64050 Len=0
62194 10:37:32.984545000 192.168.1.48 192.168.1.251 TCP 60 [TCP Dup ACK 62192#1] 49628→80 [ACK] Seq=253 Ack=1 Win=2048 Len=0
62195 10:37:32.984570000 192.168.1.251 192.168.1.48 HTTP 744 [TCP Retransmission] HTTP/1.1 200 OK (text/html)HTTP/1.1 400 Bad Request (text/html)

In my client i wait for chars like this:

//wait for chars to read (more than 0)
while (!client.available())
{
delay(1);
sWait++;
if (sWait>250)
{
print.MyPrintln(“No chars to read from stream”, bDebugMode);
break;
}
}

and than reads all the chars in a different loop.

I don’t know if this packet loss a normal thing on arduino as a client.
What could it be?

You should post all your code. That snippet is not enough to determine what the problem is.

I can’t post all of my code (it’s a very long one), but i’m posting some of it as an example:

a function that creates a JSON string and posts it to the server:

void AskWhatToDoFromServer()
{
String strRequest;
byte * RequstResult;
short RequestSize=0;

if(client.connect(serverIP, 80))
{
print.MyPrintln(“connected”, bDebugMode);
strRequest="{“actionNumber”:1,";


SendDataToServer(m_bIsEncrypted, strRequest);
ReadServerResponse();
}
else
{
print.MyPrintln(“Not Connected”, bDebugMode);
}
}

SendDataToServer (in out case, the JSON string+other ID headers)

void SendDataToServer(bool bIsEncrypted, String strData)
{
byte * RequstResult=NULL;
short RequestSize=0;
client.print(“POST http://myServer/JSON”); //debug on my local pc
client.print(" HTTP/1.1\r\n");
client.println(“Host: myserver:80”);
print.MyPrint("Content-Length: ", bDebugMode);
print.MyPrintln(RequestSize*3 +24, bDebugMode);
client.print("Content-Length: ");
client.println(strData.length() +24);
client.println(“Content-Type: json ; charset=UTF-8”);
client.println(“Connection: keep-alive\r\n”);

// add info to body: ardID + counter
client.print("ARD: ");
print.MyPrint(“ARD: “,bDebugMode);
client.print(ArdID, HEX);
print.MyPrint(ArdID, HEX, bDebugMode);
client.print(” COMM COUNT: “);
print.MyPrint(” COMM COUNT: “, bDebugMode);
client.print(lMsgCounter, HEX);
print.MyPrint(lMsgCounter, HEX, bDebugMode);
print.MyPrint(” “, bDebugMode);
if (strData.length()>1500)//splits long message if needed
{
print.MyPrintln(“more than 1500 bytes”, bDebugMode);
int nLengthSent=0;
while ( nLengthSent < strData.length() )
{
char buff[1500] ={0};
int copySize = min(1500,strData.length());
memcpy(&buff, &strData[nLengthSent], copySize-1);
buff[1499]=NULL;
client.print(buff);
nLengthSent += copySize-1;
}
client.println();
}
else
{
client.print(strData);
}
print.MyPrint(strData, bDebugMode);

client.println(); //important!
print.MyPrintln(“request sent”, bDebugMode);
}
lMsgCounter++;
strData=””;
}

ReadServerResponse (copied most of it from the forums, in order to ignore /n):

void ReadServerResponse()
{
//char responseFromServer=‘a’;
boolean currentLineIsBlank = true;
boolean bIsRead = false;
short sWait=0;
IncomingPostData="";
print.MyPrintln("", bDebugMode);
while(client.connected())
{
//wait for chars to read (more than 0)
while (!client.available())
{
delay(1);
sWait++;
if (sWait>250)
{
print.MyPrintln(“No chars to read from stream”, bDebugMode);
break;
}
}

print.MyPrint("sWait is: ", bDebugMode);
print.MyPrintln(sWait, bDebugMode);
while (client.available())
{
char c = client.read();
print.MyPrint(c, bDebugMode);
if (m_bIsEncrypted)
{
if (c == ‘\n’ && currentLineIsBlank)
{
// Here is where the POST data is.
while(client.available())
{
if (bIsRead ==true)
{
client.read();
}
//Serial.write(client.read());
char read = (char)client.read();
if (read>=‘0’ && read<=‘9’ || read>=‘A’ &&read<=‘F’ || read==’ ')
{
IncomingPostData += read;
}
else
{
bIsRead = true;
break;
}

}
}
else if (c == ‘\n’)
{
// you’re starting a new line
currentLineIsBlank = true;
}
else if (c != ‘\r’)
{
// you’ve gotten a character on the current line
currentLineIsBlank = false;
}
}
else //not encrypted
{
if (c == ‘\n’ && currentLineIsBlank)
{
//body
while(client.available())
{
c=client.read();
IncomingPostData += c;
}
}
else if (c == ‘\n’)
{
// you’re starting a new line
currentLineIsBlank = true;
}
else if (c != ‘\r’)
{
// you have a character on the current line
currentLineIsBlank = false;
}

}
}
client.stop();
print.MyPrint(“Body is: “, bDebugMode);
print.MyPrintln(IncomingPostData, bDebugMode);
print.MyPrintln(””, bDebugMode);
}
}

Note: The print.MyPrint/ln() function is very similar to Serial.print only prints when in debug-Mode.

How often do you send this request?

most of the times in intervals of 3 sec, but it can go down to 100 milisec. I've seen it goes bad in both cases.

Have you tried any other client code with your server? Here is mine.
http://playground.arduino.cc/Code/WebClient
Try this with a standard webpage on your server for a while and see if you get a fail with it.,

I tried some other but it didn't quite fit out of technical reasons (parsing the responses from the server).
I think that i'm on something here, i disabled the polling mechanism:

while (!client.available())
{
delay(1);
sWait++;
if (sWait>250)
{
print.MyPrintln("No chars to read from stream", bDebugMode);
break;
}
}

And instead i put a constant "delay(250)" and after testing it for a couple of minutes i think that it really helps.
So what happened here? is the client.Available() function prevents the write to the buffer somehow?
The thing is that i want the program to respond as fast as possible after the response from the server arrives. This delay time might change if i upload my server or something like that. I will really appreciate if someone can point me to that direction.

I use a 1ms delay between packets just for the timeout feature. Any more than that is not necessary.

ok nevermind, it's not a solution for my problem. I'll try your client.
Thanks!