tcp_output() when processing "tcp_input_pcb"

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

tcp_output() when processing "tcp_input_pcb"

Numb_Faith
When I use lwip1.4.1 and RAW API, I meet a problem. I use my borad(STM32) as a server. When server receive a packet from client, I hope it can send a packet immediately. So I call the function below:

tcp_write(tpcb, DataTest, sizeof(DataTest), 0x01);
tcp_output(tpcb);


But when server receive a packet, the stack will call tcp_input(), and tcp_input_pcb = pcb (the connection), so tcp_output(tpcb) would return.

When I comment the code below(in function tcp_output), it can got what I want. But I'm still confused about why "If we are invoked by the TCP input processing code, we do not output anything".

/* First, check if we are invoked by the TCP input processing code. If so, we do not output anything.
    Instead, we rely on the input processing code to call us when input processing is done with. */
//  if (tcp_input_pcb == pcb) {
//  return ERR_OK;
//  }

Best Regards,
Ray Li
Reply | Threaded
Open this post in threaded view
|

Re: tcp_output() when processing "tcp_input_pcb"

Bill Auerbach
Ray,

Perhaps you can show us your connection setup code (i.e. the tcp alloc,
listen, bind, etc.).

Bill

-----Original Message-----
From: lwip-users-bounces+bauerbach=[hidden email]
[mailto:lwip-users-bounces+bauerbach=[hidden email]] On Behalf
Of Numb_Faith
Sent: Friday, August 09, 2013 3:46 AM
To: [hidden email]
Subject: [lwip-users] tcp_output() when processing "tcp_input_pcb"

When I use lwip1.4.1 and RAW API, I meet a problem. I use my borad(STM32) as
a server. When server receive a packet from client, I hope it can send a
packet immediately. So I call the function below:

/tcp_write(tpcb, DataTest, sizeof(DataTest), 0x01); tcp_output(tpcb);/

But when server receive a packet, the stack will call tcp_input(), and
tcp_input_pcb = pcb (the connection), so tcp_output(tpcb) would return.

When I comment the code below(in function tcp_output), it can got what I
want. But I'm still confused about why "If we are invoked by the TCP input
processing code, we do not output anything".

/* First, check if we are invoked by the TCP input processing code. If so,
we do not output anything.
    Instead, we rely on the input processing code to call us when input
processing is done with. */ //  if (tcp_input_pcb == pcb) { //  return
ERR_OK; //  }

Best Regards,
Ray Li



--
View this message in context:
http://lwip.100.n7.nabble.com/tcp-output-when-processing-tcp-input-pcb-tp217
83.html
Sent from the lwip-users mailing list archive at Nabble.com.

_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users


_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: tcp_output() when processing "tcp_input_pcb"

Numb_Faith
Hi Bill,

Certainly, I can show my code. But I think that I set up the server successfully. My problem is how to send packets immediatly(when I turn off the nagle.) The "tcp_output()" is in the last line.

/**
  * @brief  Initializes the tcp echo server
  * @param  None
  * @retval None
  */
void tcp_echoserver_init(void)
{
  /* create new tcp pcb */
  tcp_echoserver_pcb = tcp_new();

  if (tcp_echoserver_pcb != NULL)
  {
    err_t err;
   
    /* bind echo_pcb to port 7 (ECHO protocol) */
    err = tcp_bind(tcp_echoserver_pcb, IP_ADDR_ANY, 7);
   
    if (err == ERR_OK)
    {
      /* start tcp listening for echo_pcb */
      tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);
     
      /* initialize LwIP tcp_accept callback function */
      tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);
    }
    else
    {
      /* deallocate the pcb */
      memp_free(MEMP_TCP_PCB, tcp_echoserver_pcb);
     }
  }
  else
  {
    printf("Can not create new pcb\n");
  }
}

/**
  * @brief  This function is the implementation of tcp_accept LwIP callback
  * @param  arg: not used
  * @param  newpcb: pointer on tcp_pcb struct for the newly created tcp connection
  * @param  err: not used
  * @retval err_t: error status
  */
static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
  err_t ret_err;
  struct tcp_echoserver_struct *es;

  LWIP_UNUSED_ARG(arg);
  LWIP_UNUSED_ARG(err);

  /* set priority for the newly accepted tcp connection newpcb */
  tcp_setprio(newpcb, TCP_PRIO_MIN);

  /* allocate structure es to maintain tcp connection informations */
  es = (struct tcp_echoserver_struct *)mem_malloc(sizeof(struct tcp_echoserver_struct));
  if (es != NULL)
  {
    es->state = ES_ACCEPTED;
    es->pcb = newpcb;
    es->p = NULL;
   
    /* pass newly allocated es structure as argument to newpcb */
    tcp_arg(newpcb, es);
   
    /* initialize lwip tcp_recv callback function for newpcb  */
    tcp_recv(newpcb, tcp_echoserver_recv);
   
    /* initialize lwip tcp_err callback function for newpcb  */
    tcp_err(newpcb, tcp_echoserver_error);
   
    /* initialize lwip tcp_poll callback function for newpcb */
    tcp_poll(newpcb, tcp_echoserver_poll, 1);
   
    ret_err = ERR_OK;
  }
  else
  {
    /*  close tcp connection */
    tcp_echoserver_connection_close(newpcb, es);
    /* return memory error */
    ret_err = ERR_MEM;
  }

  return ret_err;  
}


/**
  * @brief  This function is the implementation for tcp_recv LwIP callback
  * @param  arg: pointer on a argument for the tcp_pcb connection
  * @param  tpcb: pointer on the tcp_pcb connection
  * @param  pbuf: pointer on the received pbuf
  * @param  err: error information regarding the reveived pbuf
  * @retval err_t: error code
  */
static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
  struct tcp_echoserver_struct *es;
  err_t ret_err;

  LWIP_ASSERT("arg != NULL",arg != NULL);
 
  es = (struct tcp_echoserver_struct *)arg;
 
  tcp_nagle_disable(tpcb);

  tcp_write(tpcb, DataTest, sizeof(DataTest), 0x01);
   
  tcp_output(tpcb);                            // return
  ...
}

Best Regards,
Ray Li
Reply | Threaded
Open this post in threaded view
|

Re: tcp_output() when processing "tcp_input_pcb"

Valery Ushakov
In reply to this post by Numb_Faith
Numb_Faith <[hidden email]> wrote:

> When I use lwip1.4.1 and RAW API, I meet a problem. I use my borad(STM32) as
> a server. When server receive a packet from client, I hope it can send a
> packet immediately. So I call the function below:
>
> /tcp_write(tpcb, DataTest, sizeof(DataTest), 0x01);
> tcp_output(tpcb);/
>
> But when server receive a packet, the stack will call tcp_input(), and
> tcp_input_pcb = pcb (the connection), so tcp_output(tpcb) would return.
>
> When I comment the code below(in function tcp_output), it can got what I
> want. But I'm still confused about why "If we are invoked by the TCP input
> processing code, we do not output anything".
>
> /* First, check if we are invoked by the TCP input processing code. If so,
> we do not output anything.
>    Instead, we rely on the input processing code to call us when input
> processing is done with. */
> //  if (tcp_input_pcb == pcb) {
> //  return ERR_OK;
> //  }

Input processing code _does_ call tcp_output() at:

http://git.savannah.gnu.org/cgit/lwip.git/tree/src/core/tcp_in.c?h=DEVEL-1_4_1#n381

        tcp_input_pcb = NULL;
        /* Try to send something out. */
        tcp_output(pcb);

At that point input processing is complete and pcb is in consistent
state, etc, etc, so tcp_output() doesn't have to be concerned with
possible iteractions with tcp_input().

-uwe


_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: tcp_output() when processing "tcp_input_pcb"

Noam weissman
Hi,

I am not sure I understand your problem but if I did understand, you please see below.

In RAW mode you have just one task that runs all your TCP/IP connections and servers.
One task means that every time you do something related to TCP only this part is running
And nothing else is working.

LwIP has its own house housekeeping operations (ACK, SYN, etc.....).

When you get a packet dedicated to your server, your own call back is triggered. You process
the data and call tcp_write

tcp_write adds a buffer to the list of buffers to be sent. But and here comes the BIG but. The code
that is sending the data (inside LwIP) will never be called if you do not exit from your own function
and let the stack do its housekeeping tasks.

You cannot expect the data to be sent at zero delay after you put it to be sent.

I hope now it is clear.

BR,
Noam.

-----Original Message-----
From: lwip-users-bounces+noam=[hidden email] [mailto:lwip-users-bounces+noam=[hidden email]] On Behalf Of Valery Ushakov
Sent: ב 12 אוגוסט 2013 22:40
To: [hidden email]
Subject: Re: [lwip-users] tcp_output() when processing "tcp_input_pcb"

Numb_Faith <[hidden email]> wrote:

> When I use lwip1.4.1 and RAW API, I meet a problem. I use my
> borad(STM32) as a server. When server receive a packet from client, I
> hope it can send a packet immediately. So I call the function below:
>
> /tcp_write(tpcb, DataTest, sizeof(DataTest), 0x01); tcp_output(tpcb);/
>
> But when server receive a packet, the stack will call tcp_input(), and
> tcp_input_pcb = pcb (the connection), so tcp_output(tpcb) would return.
>
> When I comment the code below(in function tcp_output), it can got what
> I want. But I'm still confused about why "If we are invoked by the TCP
> input processing code, we do not output anything".
>
> /* First, check if we are invoked by the TCP input processing code. If
> so, we do not output anything.
>    Instead, we rely on the input processing code to call us when input
> processing is done with. */ //  if (tcp_input_pcb == pcb) { //  return
> ERR_OK; //  }

Input processing code _does_ call tcp_output() at:

http://git.savannah.gnu.org/cgit/lwip.git/tree/src/core/tcp_in.c?h=DEVEL-1_4_1#n381

        tcp_input_pcb = NULL;
        /* Try to send something out. */
        tcp_output(pcb);

At that point input processing is complete and pcb is in consistent state, etc, etc, so tcp_output() doesn't have to be concerned with possible iteractions with tcp_input().

-uwe


_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users

 
 
************************************************************************************
This footnote confirms that this email message has been scanned by PineApp Mail-SeCure for the presence of malicious code, vandals & computer viruses.
************************************************************************************




 
 
************************************************************************************
This footnote confirms that this email message has been scanned by
PineApp Mail-SeCure for the presence of malicious code, vandals & computer viruses.
************************************************************************************




_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: tcp_output() when processing "tcp_input_pcb"

Numb_Faith
Dear Noam,

Thanks, I'm clear about it.
So if I want to do some application which need real time, I still need the RTOS. Though TCP/IP is not a stack which has good performance in the real time case.

Best Regards,
Ray Li
Reply | Threaded
Open this post in threaded view
|

Re: tcp_output() when processing "tcp_input_pcb"

Noam weissman
Hi,

It depends on what you do and what are the available resources (RAM/ROM).

LwIP is small but it has its limitations.

I am working with a system that has a WEB server, UDP and TCP connections and bridging to UART
all is running at real time.

If you do not need exceptional throughput its OK.

BR,
Noam.

-----Original Message-----
From: lwip-users-bounces+noam=[hidden email] [mailto:lwip-users-bounces+noam=[hidden email]] On Behalf Of Numb_Faith
Sent: ג 13 אוגוסט 2013 12:38
To: [hidden email]
Subject: Re: [lwip-users] tcp_output() when processing "tcp_input_pcb"

Dear Noam,

Thanks, I'm clear about it.
So if I want to do some application which need real time, I still need the RTOS. Though TCP/IP is not a stack which has good performance in the real time case.

Best Regards,
Ray Li



--
View this message in context: http://lwip.100.n7.nabble.com/tcp-output-when-processing-tcp-input-pcb-tp21783p21793.html
Sent from the lwip-users mailing list archive at Nabble.com.

_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users

 
 
************************************************************************************
This footnote confirms that this email message has been scanned by PineApp Mail-SeCure for the presence of malicious code, vandals & computer viruses.
************************************************************************************




 
 
************************************************************************************
This footnote confirms that this email message has been scanned by
PineApp Mail-SeCure for the presence of malicious code, vandals & computer viruses.
************************************************************************************




_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: tcp_output() when processing "tcp_input_pcb"

Bill Auerbach
Hi,

I agree with you.  We are running real-time with RAW API and NO OS and see
very good TCP response - but we are on a fast system.  On our lower
performing systems we get "exceptional throughput" only by using UDP.

Also, the real-time part of lwIP is maximized by minimizing what you do in
the receive callback.  If you do too much in the receive callback, you throw
off TCP timing which slows the connection even to the point of causing
errors.  If I need more than a few milliseconds, I kick off a second thread
so I can return to lwIP as fast as possible.  We run a cooperative OS which
eliminates all of the threading problems of lwIP.

Bill

-----Original Message-----
From: lwip-users-bounces+bauerbach=[hidden email]
[mailto:lwip-users-bounces+bauerbach=[hidden email]] On Behalf
Of Noam weissman
Sent: Tuesday, August 13, 2013 5:51 AM
To: Mailing list for lwIP users
Subject: Re: [lwip-users] tcp_output() when processing "tcp_input_pcb"

Hi,

It depends on what you do and what are the available resources (RAM/ROM).

LwIP is small but it has its limitations.

I am working with a system that has a WEB server, UDP and TCP connections
and bridging to UART all is running at real time.

If you do not need exceptional throughput its OK.

BR,
Noam.

-----Original Message-----
From: lwip-users-bounces+noam=[hidden email]
[mailto:lwip-users-bounces+noam=[hidden email]] On Behalf Of
Numb_Faith
Sent: ג 13 אוגוסט 2013 12:38
To: [hidden email]
Subject: Re: [lwip-users] tcp_output() when processing "tcp_input_pcb"

Dear Noam,

Thanks, I'm clear about it.
So if I want to do some application which need real time, I still need the
RTOS. Though TCP/IP is not a stack which has good performance in the real
time case.

Best Regards,
Ray Li



--
View this message in context:
http://lwip.100.n7.nabble.com/tcp-output-when-processing-tcp-input-pcb-tp217
83p21793.html
Sent from the lwip-users mailing list archive at Nabble.com.

_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users

 
 
****************************************************************************
********
This footnote confirms that this email message has been scanned by PineApp
Mail-SeCure for the presence of malicious code, vandals & computer viruses.
****************************************************************************
********




 
 
****************************************************************************
********
This footnote confirms that this email message has been scanned by PineApp
Mail-SeCure for the presence of malicious code, vandals & computer viruses.
****************************************************************************
********




_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users


_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users