lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] netconn_recv blocking forever


From: Timmy Brolin
Subject: Re: [lwip-users] netconn_recv blocking forever
Date: Thu, 08 Mar 2007 23:15:26 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax)

I can only agree with Mateusz.
The raw API is very easy to work with. I think it is actually easier to use than the socket API in many cases. The performance benefits and memory savings of the raw API certainly does not hurt either :-) But if you still want to use the socket API, using select() with a timeout should solve your problem.

Regards,
Timmy Brolin

Çağlar AKYÜZ wrote:

Mateusz Plocinski wrote:

Hi,
I'm using an ARM7 FreeRTOS port of lwip. I'm trying to implement a
thread which waits for data from PC using netconn_recv. Everything
works fine in most situations (for week or longer without any
problems), but when I disconnect network cable or PC simply hangs up
without closing a connection, my lwip socket thread still sits in
netconn_recv function.

Is there any way to check if connection isnt dead while thread is
blocked in netconn_recv? I need to know in few seconds if I should
close connection because I need to quickly restart connection to my
ARM hardware (and I have only on thread so I cant open more sockets to
wait for connection).


Just don't use netconn_recv. Instead use raw api with callbacks enabled. Then sleep in your task with vTaskDelayUntil api of FreeRTOS. This way if something goes wrong, you won't be blocking
forever in netconn_recv and you will have a chance to correct things up.

There is a nice code in the list illustrating the use of raw api. I'm using this code happly with my SAM7X with FreeRTOS installed. I searched thru the list but unable to find the link. So I'm attaching my own modified version.

By the way, using raw api is not that much hard. I was able to migrate my code from netconn api to raw api in hours keeping
in mind that I'm not a code guru. Just give it a try.

Regards
Caglar AKYUZ


err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
/* This callback function is called when stack receives data from the MAC
    * interface(on our port of course). Then we can process this message
    */    static int settings[SETTINGS_LENGTH];
   (void) arg;
   if (err == ERR_OK && p != NULL)
   {
       /* if config_mode is not 0, then we are in configuration mode */
       if( config_mode ) {
configure_device_tcp( &settings[0] , pcb , p ); } else {
           /* Process message then if we are not in config mode */
process_tcp_message( &settings[0] , pcb , p ); } /* Acknowledge stack that we have processed the message so that it can
        * inrcrease window size
       ,
        */
       tcp_recved(pcb, p->tot_len);
       /* Never forget to free a buffer! */
       pbuf_free(p);          }
   else
       pbuf_free(p); /* Never forget to free a buffer! */

   if (err == ERR_OK && p == NULL)
   {
/* If we are here this means that other side has closed the connection. */
       tcp_arg(pcb, NULL);
       tcp_sent(pcb, NULL);
       tcp_recv(pcb, NULL);
       tcp_close(pcb);
       pioA_toggle_led( 1 );
/* Inform mac task that communication is closed. Otherwise, it will immediately * send conversion data as soon as a client arrives without waiting the
        * send commdand.
        */
       comm_open = 0;
   }
   return ERR_OK;
}

err_t netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
/* When there is a connection request this function is called by the stack */
   (void) arg;
   (void) err;
   tcp_arg(pcb, NULL);
   tcp_sent(pcb, NULL);
/* Inform stack about which function to call-back when there is data on the line */
   tcp_recv(pcb, netio_recv);
/* Hold the accepted connection pcb. This will used later when we desire to send
    * data asynchronously from the receive callback function
    */
   netio_pcb = pcb;
   pioA_toggle_led( 0 );
   return ERR_OK;
}

struct tcp_pcb* netio_init(void)
{
/* This function initalizes the connection. We start listenin on the desired port * and our defined callback function to be called by the stack when someone
    * arrives
    */
   struct tcp_pcb *pcb;
     pcb = tcp_new();
   tcp_bind(pcb, IP_ADDR_ANY, SETTINGS_PAGE[LOCAL_PORT]);
   pcb = tcp_listen(pcb);      tcp_accept(pcb, netio_accept);
   return pcb;
}



_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users






reply via email to

[Prev in Thread] Current Thread [Next in Thread]