ESP8266 as TCP server

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

ESP8266 as TCP server

Postby ESP_Faye » Thu Jul 16, 2015 9:58 am

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.
1. Start from user_init
2. ESP8266 is in station mode and connect to a router
3. Set up a TCP server listening to TCP client
4. If TCP server received data from TCP client, it will reply the same data back to TCP client.

Code: Select all

#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"
#include "espconn.h"

LOCAL struct espconn esp_conn;
LOCAL esp_tcp esptcp;

#define SERVER_LOCAL_PORT   1112

/******************************************************************************
 * FunctionName : tcp_server_sent_cb
 * Description  : data sent callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
tcp_server_sent_cb(void *arg)
{
   //data sent successfully

    os_printf("tcp sent cb \r\n");
}


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

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

/******************************************************************************
 * FunctionName : tcp_server_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
tcp_server_recon_cb(void *arg, sint8 err)
{
   //error occured , tcp connection broke.
   
    os_printf("reconnect callback, error code %d !!! \r\n",err);
}

LOCAL void tcp_server_multi_send(void)
{
   struct espconn *pesp_conn = &esp_conn;

   remot_info *premot = NULL;
   uint8 count = 0;
   sint8 value = ESPCONN_OK;
   if (espconn_get_connection_info(pesp_conn,&premot,0) == ESPCONN_OK){
      char *pbuf = "tcp_server_multi_send\n";
      for (count = 0; count < pesp_conn->link_cnt; count ++){
         pesp_conn->proto.tcp->remote_port = premot[count].remote_port;
         
         pesp_conn->proto.tcp->remote_ip[0] = premot[count].remote_ip[0];
         pesp_conn->proto.tcp->remote_ip[1] = premot[count].remote_ip[1];
         pesp_conn->proto.tcp->remote_ip[2] = premot[count].remote_ip[2];
         pesp_conn->proto.tcp->remote_ip[3] = premot[count].remote_ip[3];

         espconn_sent(pesp_conn, pbuf, os_strlen(pbuf));
      }
   }
}


/******************************************************************************
 * FunctionName : tcp_server_listen
 * Description  : TCP server listened a connection successfully
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
tcp_server_listen(void *arg)
{
    struct espconn *pesp_conn = arg;
    os_printf("tcp_server_listen !!! \r\n");

    espconn_regist_recvcb(pesp_conn, tcp_server_recv_cb);
    espconn_regist_reconcb(pesp_conn, tcp_server_recon_cb);
    espconn_regist_disconcb(pesp_conn, tcp_server_discon_cb);
   
    espconn_regist_sentcb(pesp_conn, tcp_server_sent_cb);
   tcp_server_multi_send();
}

/******************************************************************************
 * FunctionName : user_tcpserver_init
 * Description  : parameter initialize as a TCP server
 * Parameters   : port -- server port
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_tcpserver_init(uint32 port)
{
    esp_conn.type = ESPCONN_TCP;
    esp_conn.state = ESPCONN_NONE;
    esp_conn.proto.tcp = &esptcp;
    esp_conn.proto.tcp->local_port = port;
    espconn_regist_connectcb(&esp_conn, tcp_server_listen);

    sint8 ret = espconn_accept(&esp_conn);
   
    os_printf("espconn_accept [%d] !!! \r\n", ret);

}
LOCAL os_timer_t test_timer;

/******************************************************************************
 * FunctionName : user_esp_platform_check_ip
 * Description  : check whether get ip addr or not
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_esp_platform_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");
      user_tcpserver_init(SERVER_LOCAL_PORT);

    } 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_esp_platform_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_esp_platform_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  station mode
   wifi_set_opmode(STATIONAP_MODE);

   // ESP8266 connect to router.
   user_set_station_config();
   
}


TCP_Server_Example_02.zip
This is another example of ESP8266 working as TCP server with multiple TCP connections.
(1.03 KiB) Downloaded 3278 times

PaulTsai111
Posts: 48
Joined: Wed May 04, 2016 7:32 pm

Re: ESP8266 as TCP server

Postby PaulTsai111 » Wed May 18, 2016 10:46 am

Hi Espressif:

I used the sample code ESP8266 as TCP server , but after I compiling the code , it shows a lot of error messages.

what's wrong with it ? I do not know how to test that !

The codes and sim results are shown as attached files.
Attachments
22.png
11.png
33.png

Dashaduamp
Posts: 5
Joined: Mon Jun 19, 2017 10:28 am

ESP8266 as TCP server

Postby Dashaduamp » Wed Jun 21, 2017 8:05 am

Dear Sir
I am Dushyant here
i have made Vb code for Modbus Tcp/Ip. Which works as Server/Slave as well as Client/Master.
Now my software can connect with only one server at one time
so is it possible to be connected for continusly with more then one server?

andreysnug
Posts: 21
Joined: Wed May 16, 2018 12:33 pm

ESP8266 as TCP server

Postby andreysnug » Thu May 24, 2018 6:28 am

Hello ,
I have noticed some examples found in the help web page for wlan esp8266. One is the TCP server that a PC can connect the the esp8266 access point and switch on off LEDs.
The other is the TCP client that the esp8266 connects to home router and accesses matrixs web page.

Is there an example of those 2 combined?
It would be good to connect the esp8266 to home router and switch LEDs on off through the internet by enabling port forward on home router.

Thank you
Best Regards
Andreas Achilleos

Buzzardbait

Re: ESP8266 as TCP server

Postby Buzzardbait » Sat Jul 13, 2019 10:18 am

Hi, thanks for the server code but what compiler are you using? The Ardurino compiler throws many syntax errors such as "invalid conversion from 'void*' to 'espconn*' [-fpermissive]". This seems to appear anywhere you attempt to cast a pointer such as "struct espconn *pespconn = arg;". This is not a valid way of type casting. The entire code block would take a lot of effort to repair these errors.

Paulaimmef

ESP8266 as TCP server

Postby Paulaimmef » Wed Oct 16, 2019 10:49 am

I am trying to use the SBC65EC as a simple TCP/IP server that would simply receive a byte, echo it back and use that to modulate the length of a pulse. I added the code inside the while loop in the web server application without changing anything else except for the required declaration and definitions to make the code work. Here is the code I added:

while1
   
    TRISCbits.TRISC5 = 1 ;         / set RC5 for input     /
    TRISBbits.TRISB4  = 0 ;         / set RB4 for output     /

   if TCPIsConnectedtcpsocket

            if PORTCbits.RC5 == 1
            / check the input on PORTB  /
i = 0; / Initialize i/
pulse_en = 1; / set state variable/
if PORTCbits.RC5 == 0 & pulse_en == 1
            /look for an on-to-off transition/
                LATBbits.LATB4 = 1 ;  / light on if pulse         /
DelayMs1000;
LATBbits.LATB4 = 0 ;  / turn pulse off after timeout /
             
pulse_en = 0;
             
       
   
else

Socket_ok = 0;

        if TickGetDiffTickGet, t >= TICK_SECOND/pulse_rec
       
            t = TickGet;
            LATB6 = 1;
       

        //Perform routine tasks
        MACTask;

        /
          This task performs normal stack task including checking
          for incoming packet, type of packet and calling
          appropriate stack entity to process it.
         /
        StackTask;

if Socket_ok

LATBbits.LATB4 = 1 ; 
DelayMs1000;
LATBbits.LATB4 = 0 ; 

ifTCPIsGetReadytcpsocket

TCPGettcpsocket, &pulse;
DelayMs50;
pulse_rec = 8;
TCPDiscardtcpsocket;
if TCPIsPutReadytcpsocket

TCPPuttcpsocket, pulse;
DelayMs50;
TCPFlushtcpsocket;
DelayMs50;
TCPDiscardtcpsocket; //Release the buffer




else

tcpsocket = TCPListenport;
if tcpsocket = INVALID_SOCKET

Socket_ok = TRUE;





This code does connect right now over port 200. The value assigned to the port in the variable declaration. I can see that on Ethereal. However, that's all it does. It does not echo anything back. The evidence is that the pulse rate on the built-in LED does not change. I have the pulse starting out at 1 every second. And I am trying to change it to once every 1/8th of a send once the TCPGet occurs. And the pulse rate is not changing. I am also trying to turn on another LED that I added for one second once the socket is connected. That's not hapenning either. I am starting to suspect that maybe another task is getting attached. The HTTP task attaches on port 80 though, not 200. Can you help me with this?

Thanks,

Rami Salah

Who is online

Users browsing this forum: No registered users and 3 guests