|
From: | Noam Weissman |
Subject: | Re: [lwip-users] Raw api + multiple TCP Connections |
Date: | Mon, 22 May 2017 12:49:46 +0000 |
Hi, First of all read the lwip readme and every document you can find. Check the echo server example and see how it is written. 1. If both servers are the same write functions and simply pass parameters. You do not need to copy and paste the same code. Use the arg parameter in the call backs 2. If you use Lwip 1.41 the tcp_accepted function should accept the SERVER pcb and not the new connection pcb When you write a TCP server and bind it to port_x it means that the server is listening on that port. Listening means it can accept several connections at the same port.
The data transfer is not handled via the listening port but rather working port. Every connection gets a working different port… that’s TCP !!!. Your accept function is wrong. Here is my fast created code based on yours. Check it and see if it helps If you do not need two servers but rather two connections there is no need to create two servers !!! // Define type typdef struct { struct tcp_pcb *ServerPcb; u16 ServerPort; } MyServer_t; //--------------------------------- // define server variables at the same file you call init_Server function static MyServer_t Server_1, Server_2; // initialize server settings Server_1.ServerPcb = NULL; Server_1.ServerPort = PortCAN1; Server_2.ServerPcb = NULL; Server_1.ServerPort = PortCAN2; //---------------------------------------------- // function protoypes static err_t myAccept(void *arg, struct tcp_pcb *pcb, err_t err); static err_t myRecvCallback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err); // code start in main or what ever... init_Server(&Server_1); init_Server(&Server_2); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // initialize servers void init_Server(MyServer_t *Server) { struct tcp_pcb *pcb; err_t err; // create new pcb pcb = tcp_new(); if(pcb != NULL) { // bind port err = tcp_bind(pcb, IP_ADDR_ANY, Server->ServerPort); if(err == ERR_OK) { // save server pcb for later use, not the same ! Server->ServerPcb = tcp_listen(pcb); // if needed ??? tcp_setprio(Listening_pcb, TCP_PRIO_MIN);
// save argument for later use tcp_arg(Server->ServerPcb, Server); // define accept call back tcp_accept(Server->ServerPcb, accept); } else { // add error handling } } else { // add error handling } } //--------------------------------------------------------------------------- static err_t myAccept(void *arg, struct tcp_pcb *pcb, err_t err) { MyServer_t *Server = (MyServer_t*) arg; // if needed ???? // disable nagle algorithm, improve performance with winxp. tcp_nagle_disable(pcb); // do you really need TCP_PRIO_MAX ??? tcp_setprio(pcb, TCP_PRIO_MAX); // assign recv callback, only one function needed tcp_recv(pcb, myRecvCallback);
// if you use Lwip 1.41 tcp_accepted(Server->ServerPcb); return ERR_OK; } //--------------------------------------------------------------------------- static err_t myRecvCallback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { char data[8] = {1,2,3,4,5,6,7,8}; // avoid compiler warnings ( void ) arg; ( void ) err; if (!p) //end of linked list { tcp_close(tpcb); tcp_recv(tpcb, NULL); return ERR_OK; } tcp_recved(tpcb, p->tot_len); //Antwort tcp_write(tpcb, &data[0], 8, TCP_WRITE_FLAG_COPY); tcp_output(tpcb); pbuf_free(p); return ERR_OK; } I hope I do not have errors… wrote it fast
J. BR, Noam. From: lwip-users [mailto:lwip-users-bounces+address@hidden
On Behalf Of Werner Motz U are right, but I don’t know where the mistake is. I can debug it and the breakpoints in myCallback1 and myCallback2 are hit. The also debugged the init_Server and the binding or listen gave no error. Both connections are initiated correctly. I do init: void
init_Server(void) { struct
tcp_pcb
*pcb_1; struct
tcp_pcb
*pcb_2; pcb_1
=
tcp_new(); pcb_2
=
tcp_new(); tcp_bind(pcb_1,
IP_ADDR_ANY,
PortCAN1); tcp_bind(pcb_2,
IP_ADDR_ANY,
PortCAN2);
pcb_1->flags
|=
TF_NODELAY;
pcb_1->flags
|=
TF_ACK_NOW; pcb_2->flags
|=
TF_NODELAY;
pcb_2->flags
|=
TF_ACK_NOW;
tcp_arg(pcb_1,
pcb_1); tcp_arg(pcb_2,
pcb_2);
pcb_1
=
tcp_listen(pcb_1); pcb_2
=
tcp_listen(pcb_2);
tcp_accept(pcb_1,
accept); tcp_accept(pcb_2,
accept); } static
err_t
accept(void
*arg,
struct
tcp_pcb
*pcb,
err_t
err) {
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
// set the receive callback for this connection
if(pcb->local_port
==
PortCAN1)
{
tcp_setprio(pcb,
TCP_PRIO_MAX);
tcp_recv(pcb,
myCallback1);
}
else
if(pcb->local_port
==
PortCAN2)
{
tcp_setprio(pcb,
TCP_PRIO_MAX);
tcp_recv(pcb,
myCallback2);
}
// just use an integer number indicating the connection id as the
// callback argument
tcp_arg(pcb,
(void*)pcb);
// Inform lwIP that an incoming connection has been accepted.
tcp_accepted(
pcb
);
return
ERR_OK; } static
err_t
myCallback1(void
*arg,
struct
tcp_pcb
*tpcb,
struct
pbuf
*p,
err_t
err) {
// avoid compiler warnings
(
void
)
arg;
(
void
)
err;
char
data[8]
=
{1,2,3,4,5,6,7,8};
if
(!p)
//end of linked list
{
tcp_close(tpcb);
tcp_recv(tpcb,
NULL);
return
ERR_OK;
}
tcp_recved(tpcb,
p->tot_len);
//Antwort
tcp_write(tpcb,
&data[0],
8,
TCP_WRITE_FLAG_COPY);
tcp_output(tpcb);
pbuf_free(p);
return
ERR_OK; } static
err_t
myCallback2(void
*arg,
struct
tcp_pcb
*tpcb,
struct
pbuf
*p,
err_t
err) {
// avoid compiler warnings
(
void
)
arg;
(
void
)
err;
char
data[8]
=
{1,2,3,4,5,6,7,8};
if
(!p)
//end of linked list
{
tcp_close(tpcb);
tcp_recv(tpcb,
NULL);
return
ERR_OK;
}
tcp_recved(tpcb,
p->tot_len);
//Antwort
tcp_write(tpcb,
&data[0],
8,
TCP_WRITE_FLAG_COPY);
tcp_output(tpcb);
pbuf_free(p);
return
ERR_OK; } |
[Prev in Thread] | Current Thread | [Next in Thread] |