ESP8266 sends TCP packets continuously

ESP_Faye
Posts: 1646
Joined: Mon Oct 27, 2014 11:08 am

ESP8266 sends TCP packets continuously

Postby ESP_Faye » Wed Apr 01, 2015 11:29 am

:idea: :idea: :idea:
If using espconn in ESP8266_RTOS_SDK, please call espconn_init in user_init as initialization.

Sample code below is based on ESP8266_NONOS_SDK.

We suggest to call the next espconn_send in espconn_sent_callback which means that the previous packet is sent.

Or users could enable the espconn_write_finish_callback which means the data sending by espconn_send was written into the write-buffer or already sent, and call the next espconn_send in espconn_write_finish_callback.
The write-buffer can store 8 packets at most, waiting for the TCP ACK. The size of write-buffer is 2920 bytes.

Introduce an API here:

Code: Select all

Function: Set option of TCP connection
Prototype:
sint8 espconn_set_opt(
        struct espconn *espconn,
        uint8 opt
)
Parameter:
struct espconn *espconn : corresponding connected control structure
uint8 opt : Option of TCP connection
bit 0: 1: free memory after TCP disconnection happen need not wait 2 minutes;
bit 1: 1: disable nalgo algorithm during TCP data transmission, quiken the data transmission.
bit 2: 1: enable espconn_write_finish_callback.
bit 3: 1: enable TCP keep-alive function
Return:
0      : succeed
Non-0  : error (please refer to espconn.h for details.)
   e.g. ESPCONN_ARG: illegal argument,can’t find TCP connection according to structure espconn
Note:
In general, we need not call this API;
If call espconn_set_opt, please call it in TCP connected callback.



Sample code of send TCP data continually is as bellow
1. call espconn_set_opt to enable write buffer;
2. register a write finish callback;
3. send next packet in write finish callback.

Code: Select all

LOCAL os_timer_t test_timer;
LOCAL struct espconn user_tcp_conn;
LOCAL struct _esp_tcp user_tcp;
ip_addr_t tcp_server_ip;

/******************************************************************************
 * FunctionName : user_tcp_recv_cb
 * Description  : receive callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_tcp_recv_cb(void *arg, char *pusrdata, unsigned short length)
{
   //received some data from tcp connection
   
    os_printf("tcp recv !!! %s \r\n", pusrdata);
   
}
/******************************************************************************
 * FunctionName : user_tcp_sent_cb
 * Description  : data sent callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_tcp_sent_cb(void *arg)
{
   //data sent successfully

}
/******************************************************************************
 * FunctionName : user_tcp_discon_cb
 * Description  : disconnect callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_tcp_discon_cb(void *arg)
{
   //tcp disconnect successfully
   
    os_printf("tcp disconnect succeed !!! \r\n");
}

/******************************************************************************
 * FunctionName : user_tcp_write_finish
 * Description  : Data need to be sent by espconn_sent has been written into write buffer successfully,
                         call espconn_sent to send next packet is allowed.
 * Parameters   : pespconn -- the espconn used to connetion with the host
 * Returns      : none
*******************************************************************************/

LOCAL void ICACHE_FLASH_ATTR
user_tcp_write_finish(void *arg)
{
    struct espconn *pespconn = arg;
   
    espconn_sent(pespconn, "Hello World!", 12);
}

/******************************************************************************
 * FunctionName : user_sent_data
 * Description  : Processing the application data and sending it to the host
 * Parameters   : pespconn -- the espconn used to connetion with the host
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_sent_data(struct espconn *pespconn)
{

   espconn_sent(pespconn, "Hello World!", 12);
   
}

/******************************************************************************
 * FunctionName : user_tcp_connect_cb
 * Description  : A new incoming tcp connection has been connected.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_tcp_connect_cb(void *arg)
{
    struct espconn *pespconn = arg;

    os_printf("connect succeed !!! \r\n");

    espconn_regist_recvcb(pespconn, user_tcp_recv_cb);
    espconn_regist_sentcb(pespconn, user_tcp_sent_cb);
    espconn_regist_disconcb(pespconn, user_tcp_discon_cb);

    espconn_set_opt(pespconn, 0x04); // enable write buffer

    espconn_regist_write_finish(pespconn, user_tcp_write_finish); // register write finish callback
   
    user_sent_data(pespconn);
}

/******************************************************************************
 * FunctionName : user_tcp_recon_cb
 * Description  : reconnect callback, error occured in TCP connection.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_tcp_recon_cb(void *arg, sint8 err)
{
   //error occured , tcp connection broke. user can try to reconnect here.
   
    os_printf("reconnect callback, error code %d !!! \r\n",err);
}


/******************************************************************************
 * FunctionName : user_check_ip
 * Description  : check whether get ip addr or not
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_check_ip(void)
{
    struct ip_info ipconfig;

   //disarm timer first
    os_timer_disarm(&test_timer);

   //get ip info of ESP8266 station
    wifi_get_ip_info(STATION_IF, &ipconfig);

    if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0)
   {
      os_printf("got ip !!! \r\n");

      // Connect to tcp server as NET_DOMAIN
      user_tcp_conn.proto.tcp = &user_tcp;
      user_tcp_conn.type = ESPCONN_TCP;
      user_tcp_conn.state = ESPCONN_NONE;
     
      const char esp_server_ip[4] = {X, X, X, X}; // remote IP of tcp server

      os_memcpy(user_tcp_conn.proto.tcp->remote_ip, esp_server_ip, 4); // remote ip of tcp server
     
      user_tcp_conn.proto.tcp->remote_port = TCP_SERVER_PORT; // remote port of tcp server
     
      user_tcp_conn.proto.tcp->local_port = espconn_port(); //local port of ESP8266
     
      espconn_regist_connectcb(&user_tcp_conn, user_tcp_connect_cb); // register connect callback
      espconn_regist_reconcb(&user_tcp_conn, user_tcp_recon_cb); // register reconnect callback as error handler
     
      espconn_connect(&user_tcp_conn); // tcp connect


    }
   else
   {
       
        if ((wifi_station_get_connect_status() == STATION_WRONG_PASSWORD ||
                wifi_station_get_connect_status() == STATION_NO_AP_FOUND ||
                wifi_station_get_connect_status() == STATION_CONNECT_FAIL))
        {
         os_printf("connect fail !!! \r\n");
        }
      else
      {
           //re-arm timer to check ip
            os_timer_setfn(&test_timer, (os_timer_func_t *)user_check_ip, NULL);
            os_timer_arm(&test_timer, 100, 0);
        }
    }
}


/******************************************************************************
 * FunctionName : user_set_station_config
 * Description  : set the router info which ESP8266 station will connect to
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_set_station_config(void)
{
   // Wifi configuration
   char ssid[32] = "SSID";
   char password[64] = "PASSWORD";
   struct station_config stationConf;

   //need not mac address
   stationConf.bssid_set = 0;
   
   //Set ap settings
   os_memcpy(&stationConf.ssid, ssid, 32);
   os_memcpy(&stationConf.password, password, 64);
   wifi_station_set_config(&stationConf);

   //set a timer to check whether got ip from router succeed or not.
   os_timer_disarm(&test_timer);
    os_timer_setfn(&test_timer, (os_timer_func_t *)user_check_ip, NULL);
    os_timer_arm(&test_timer, 100, 0);

}


/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void user_init(void)
{
    os_printf("SDK version:%s\n", system_get_sdk_version());
   
   //Set softAP + station mode
   wifi_set_opmode(STATIONAP_MODE);

   //ESP8266 connect to router
   user_set_station_config();

}

Tiffany
Posts: 6
Joined: Thu Apr 27, 2017 11:00 am

Re: ESP8266 sends TCP packets continuously

Postby Tiffany » Wed Aug 23, 2017 4:38 pm

请问它能连续发多少次?一直发下去么。Can the packets be sent with no stopping?Or how many times in this code

Tiffany
Posts: 6
Joined: Thu Apr 27, 2017 11:00 am

Re: ESP8266 sends TCP packets continuously

Postby Tiffany » Wed Aug 23, 2017 5:15 pm

我用2秒的间隔发心跳,发了12次

Her Mary
Posts: 537
Joined: Mon Oct 27, 2014 11:09 am

Re: ESP8266 sends TCP packets continuously

Postby Her Mary » Sat Sep 30, 2017 6:48 pm

能顺畅发多少数据,主要还是看网络状况的,如果网络通畅,一直发都没问题。
如果网络堵塞,等底层缓存等待发送的 buffer 满了,还是会提示发送失败。

WarnerBoisa

ESP8266 sends TCP packets continuously

Postby WarnerBoisa » Sun Jan 13, 2019 5:51 pm

I never mentioned that some packets were lost, just that the size of the packets can be different as shown by the sniffer and the client I used. I am not trying to accuse you of any mistake I just try to understand why the length of the packet I get are different and if I can still use them. I guess that by buffering you mean that I should concatenate the data I receive in a buffer, which partly answers my message. Still no idea about the ACK message send only 1/3 times ?

Who is online

Users browsing this forum: No registered users and 4 guests