TCP: ESP8266 to PC - Only first package arrives

Hello,
I'm working on a project where I'm trying to stream bytes (in the future that will be sensor data) from an esp8266 (NodeMcu 1.0) to my computer via TCP. On my PC I have a socket running that I wrote using C++.
I generally managed to get that working, but when I don't delay the server between client.write() s, the client only catches the first char.
I really tried to understand how to exactly establish the tcp stream but I'm very confused why the other bytes never show up in my buffer. :confused:
I thought the protocol makes sure that the client has time to catch up with the data or do I have to do that manually by sending back to the server, that i recived the package befor the server sends the next one?

Server code running on esp:

#include "Arduino.h"
#include <ESP8266WiFi.h>

WiFiServer server(80);
WiFiClient client;
boolean clientConnected;

void setup()
{
  Serial.begin(115200);
  Serial.println();

  Serial.print("Setting soft-AP ... ");
  boolean result = WiFi.softAP("ESPsoftAP_01", "password");
  if (result == true)
  {
    Serial.println("Ready");
    server.begin();
    Serial.print("Connected to wifi. My address:");
    Serial.printf("Web server started, open %s in a web browser\n", WiFi.softAPIP().toString().c_str());
  }
  else
  {
    Serial.println("Failed!");
  }

  clientConnected = false;

}



void sendRandomData(int n){
    Serial.print("Sending... ");
    Serial.print(n);
    Serial.println(" Bytes");
    for(int i = n; i > 0; i--){
      char c = random(48,57);
      Serial.println(c);
      client.write(c);

      //if I add a delay here, everything works fine
    }
}

void closeClient(){
    client.write("-");
    Serial.println("stopping...");
    client.stop();
    clientConnected = false;
}

void loop()
{

  client = server.available();


  if (!clientConnected && client){
    clientConnected = true;
  }


  if(clientConnected){
    sendRandomData(10);
    closeClient();
  }


}

Client code running on my PC:

#include <iostream>
#include <fstream>
#include <Winsock2.h>
#include <windows.h>
#include <string.h>
#include <Ws2tcpip.h>
#pragma comment(lib, "libws2_32.a")

using namespace std;

char buf[4096];

int main()
{
    cout.flush();
    cout << "Programm started " << endl;
    const char *ipAdress = "192.168.4.1";
    int port = 80;

    //initialize WinSock
    WSAData data;
    WORD ver = MAKEWORD(2, 2);
    int wsResult = WSAStartup(ver, &data);
    if (wsResult != 0)
    {
        cerr << "Can't start Winsock, Err #" << wsResult << endl;
        return -1;
    }

    cout << "Winsock started" << endl;

    //create socket
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET)
    {
        cerr << "Can't create socket, Err #" << WSAGetLastError << endl;
        WSACleanup();
        return -1;
    }

    cout << "Socket created" << endl;

    //fill hint structure

    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(port);
    hint.sin_addr.s_addr = inet_addr("192.168.4.1");

    //connect to server
    int connResult = connect(sock, (sockaddr *)&hint, sizeof(hint));
    if (connResult == SOCKET_ERROR)
    {
        cerr << "Cant'connect to Server, Err #" << WSAGetLastError << endl;
        closesocket(sock);
        WSACleanup();
        return -1;
    }

    cout << "Connected to server" << endl;


    //loop

    int sendResult = send(sock, ".", 1, 0);

    boolean transmissionDone = false;

    while(!transmissionDone){
        ZeroMemory(buf, 4096);
        int bytesRecieved = 0;

            
        while(bytesRecieved == 0){

            bytesRecieved = recv(sock, buf, 4096, 0);
        }


          
        if(buf[0] == '-'){
            transmissionDone = true;
        }

        cout << ">> "<< buf[0] << endl;

        
    }
       
      
    

    cout << " Tranmission done" << endl;


    //close
    closesocket(sock);
    WSACleanup();
    return 0;
}

void handleBuffer(){

}

Thanks for your help :slight_smile:

I generally managed to get that working, but when I don't delay the server between client.write() s, the client only catches the first char.

Because your client code does exactly that: it reads the first packet and prints the first character of it. If you insert the delay call the bytes are spread over multiple packets and you print out the first byte of each packet so you might get more data on your screen, nevertheless the data is probably transferred correctly.

Have you tried a client.flush(); instad of a delay? That way you should have 1 character per packet and no delay.

The client.flush() did the trick!! I'm so happy to see the numbers rattle down the terminal in realtime! :smiley: :smiley:
Thanks for your suggestions!

The client.flush() triggers the sending of the packet without waiting. Without that the packet is send either when the buffer is full or the filling of the buffer times out iirc. Using the client.flush() is not a long term solution, you should go back and correct your code for the situation when more than one character is in a packet just as Pylon suggested.

Henning_23_23, can you share your working script? I am trying to do the same thing. Will you write the data to a file on the PC?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.