lwIP TCP client

This forum is about you. Feel free to discuss anything is related to embedded and electronics, your awesome projects, your ideas, your announcements, not necessarily related to ChibiOS but to embedded in general.
Jeroen3
Posts: 35
Joined: Wed Apr 02, 2014 10:14 am

lwIP TCP client

Postby Jeroen3 » Thu Apr 03, 2014 3:30 pm

I was looking for an example of an TCP client for lwIP, but all I could find were TCP web servers.
So I dived into lwIP to understand how to do this. Aside from noticing lwIP is a mess of half-defined functions, unclear preconditions and a lot of #ifdef settings. I managed to come up with this:

Code: Select all

#include "ch.h"
#include "hal.h"
#include "threads.h" // shared resources and semaphores
#include "chprintf.h"
#include "lwip/api.h"
#include <stdio.h>

#define cout ((BaseSequentialStream *) &SD2)

msg_t Thread2(void *arg);
WORKING_AREA(waThread2, 512);

msg_t Thread2(void *arg)
{
   // nested block to ensure cleanup of local variables since chThdExit() doesn't return!
   {
      // const for placement in ROM, static for pre-allocation in compiler instead of heap
      const systime_t t = 100;
      static uint32_t i=0;
      
      // Connection
      static struct netconn *conn;
      static ip_addr_t ip;   
      IP4_ADDR(&ip, 192,168,5,10);
      // Payload
      const char buf[] = "This is a test, system time is now ";
      static char send_cache[64];
      // Error checking
      static err_t err;
      
      // Name thread
      chRegSetThreadName("tcp_conn");
      
      // Forever, unless requested to terminate
      while (!chThdShouldTerminate()) {
         // Create new connection
         conn = netconn_new( NETCONN_TCP );
         // Suggest this local port (doesn't always work)
         netconn_bind(conn, IP_ADDR_ANY, 1234 );
         // Set timeout, otherwise netconn_write() won't fail
         netconn_set_sendtimeout(conn, 1000);
         // Connect to ip
         err = netconn_connect(conn, &ip, 1235 );
         // Verify connection
         if(err != ERR_OK){
            // Report failed
            chSemWait(&coutLock);
            chprintf(cout, "tcp could not connect\r\n");
            chSemSignal(&coutLock);
         }else{
            // Continously send a datastring with systime
            do{
               // Assemble datastring in cache
               uint32_t size = sprintf(send_cache,"%s%d\r\n", buf, chTimeNow());
               // Write cache to tcp, blocking without copy to lwip data
               err = netconn_write(conn, send_cache, size, NETCONN_NOCOPY);
               // Blink a led
               palTogglePad(GPIOD, GPIOD_LED4);
               // Report success
               chSemWait(&coutLock);
               chprintf(cout, "tcp %010d, %d\r\n", chTimeNow(), i++);
               chSemSignal(&coutLock);
               // Wait a while
               chThdSleepMilliseconds(t);
               // Check for success
            }while(err == ERR_OK && !chThdShouldTerminate());
               // report disconnect
               chSemWait(&coutLock);
               chprintf(cout, "tcp disconnected %d\r\n", netconn_err(conn));
               chSemSignal(&coutLock);
         }
         // Failed, close connection (probably caused by a disconnect or ignore by the server)
         netconn_close(conn);
         // Delete connection and start over
         netconn_delete(conn);      
         // Delay, otherwise the cout will flood (the pc cannot keep up)
         chThdSleepMilliseconds(1000);
      } // end of while
   } // end of block
   chThdExit(0);
   return 0;
}

I'm convinced this can serve as an example with at least some quality, please improve if you disagree.

Return to “User Projects”

Who is online

Users browsing this forum: No registered users and 1 guest