lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] questions on lwip (two TCP/IP sockets)


From: Jeff Barber
Subject: Re: [lwip-users] questions on lwip (two TCP/IP sockets)
Date: Wed, 11 Aug 2010 11:24:34 -0400

On Wed, Aug 11, 2010 at 10:02 AM, shogun <address@hidden> wrote:
[snip]
> From reading the documentation, rawapi.txt  “The tcp_listen() function
> returns a new connection identifier, and the one passed as an argument to
> the function will be deallocated. The reason for this behavior is that less
> memory is needed for a connection that is listening, so tcp_listen() will
> reclaim the memory needed for the original connection andallocate a new
> smaller memory block for the listening connection.”  It would appear I no
> longer need the original pointer that the tcp_new(); returns but I find I
> need to keep  a copy of the pointer from new to use with the send
> functions.

When a connection is created to your server by a remote client, lwIP
allocates a *new* PCB representing the fully connected session (not to
be confused with the new one allocated by tcp_listen). This new PCB is
passed to your accept callback.  *This* is the PCB you should be using
in all further send and receive operations on the session. The fact
that you have had any success whatsoever is (I'm guessing) due to the
fact that the next attempt to allocate a PCB -- during accept
processing -- just happens to get the same memory space that was freed
up when you called tcp_listen.

That is,
Pcb #1 is returned by tcp_new()
Pcb #2 is returned by tcp_listen().  Pcb #1 is freed here.
<Connect request arrives>
Pcb #3 is allocated internally by the stack and passed to your accept
callback.  #3 is unique to the session (i.e.
remote-ipaddr/local-ipaddr/remote-port/local-port).

If a different client were to connect to the same listening port, the
stack would create a unique pcb #4 for *that* session, which would
have a different remote-ipaddr and/or different remote-port.

> Can someone shed some light on this and help me understand this better and
> why when I try to use both sockets at once the connect order matters?

The above also explains this.  Each of your two servers will be passed
its own unique PCB.  There should be no problem in using them both
simultaneously if you use the PCB passed to the accept callback.

A few other comments below.

[snip]
> err_t socket_new_accept(void *arg, struct tcp_pcb *pcb, err_t err)

                          ^^^^
Save this argument as the value of newSock_pcb.  Actually, in the
dead-simple server you have implemented, you don't even need to save
the pcb as it will be passed to your recv callback below anyway,
though you will need to pass the pcb to your sending function as well.


> static err_t socket_new_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p,
> err_t err )
>
> {
[snip]
>                                 ert = pbuf_free(p);
>
>                                 while(p->next) //see if next contains a non
> NULL pointer
>                                 {
>                                                 ert = pbuf_free(p->next);
>                                                 if(ert)
>                                                 {
>                                                                 UARTprintf("
> error (%d) freeing data at %x\n", ert, p->next);
>                                                 }
>                                                 p = p->next;
>                                 }//end clean up memory
>
[snip]
>                                 ert = pbuf_free(p);

You should only be calling pbuf_free once, and if the pbuf is chained,
pbuf_free will chase the chain for you, you do not need to do so.
(And if you did need to chase the chain, it's generally not a good
idea to be looking at a data structure's contents after you've freed
it, as you're doing here.)

Jeff



reply via email to

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