我有 tcp_server 的基本应用程序。
- void tcp_echoserver_init( uint16_t port)
- {
- tcp_echoserver_PCB = tcp_new();
- if ( tcp_echoserver_pcb != NULL)
- {
- err_t err;
- /* bind echo_pcb to port (ECHO protocol) */
- err = tcp_bind( tcp_echoserver_pcb, IP_ADDR_ANY, port);
- 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 );
- }
- }
- }
- static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
- {
- err_t ret_err;
- struct echoserver *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 echoserver *)mem_malloc(sizeof(struct echoserver));
- if (es != NULL)
- {
- es->state = ES_ACCEPTED;
- es->pcb = newpcb; //newpcb;
- es->retries = 0;
- 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, 0);
- ret_err = ERR_OK;
- }
- else
- {
- /* close tcp connection */
- tcp_echoserver_connection_close(newpcb, es);
- /* return memory error */
- ret_err = ERR_MEM;
- }
- return ret_err;
- }
- static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
- {
- struct echoserver *es;
- err_t ret_err;
- LWIP_ASSERT("arg != NULL",arg != NULL);
- es = (struct echoserver *)arg;
- /* if we receive an empty tcp frame from client => close connection */
- if (p == NULL)
- {
- /* remote host closed connection */
- es->state = ES_CLOSING_SERVER;
- if(es->p == NULL)
- {
- /* we're done sending, close connection */
- tcp_echoserver_connection_close(tpcb, es);
- }
- else
- {
- /* we're not done yet */
- /* acknowledge received packet */
- tcp_sent(tpcb, tcp_echoserver_sent);
- /* send remaining data*/
- tcp_echoserver_send(tpcb, es);
- }
- ret_err = ERR_OK;
- }
- /* else : a non empty frame was received from client but for some reason err != ERR_OK */
- else if(err != ERR_OK)
- {
- /* free received pbuf*/
- if (p != NULL)
- {
- es->p = NULL;
- pbuf_free(p);
- }
- ret_err = err;
- }
- else if(es->state == ES_ACCEPTED)
- {
- /* first data chunk in p->payload */
- es->state = ES_RECEIVED_SERVER;
- /* store reference to incoming pbuf (chain) */
- es->p = p;
- /* initialize LwIP tcp_sent callback function */
- tcp_sent(tpcb, tcp_echoserver_sent);
- /* send back the received data (echo) */
- tcp_echoserver_send(tpcb, es);
- ret_err = ERR_OK;
- }
- else if (es->state == ES_RECEIVED_SERVER)
- {
- /* more data received from client and previous data has been already sent*/
- if(es->p == NULL)
- {
- es->p = p;
- /* send back received data */
- tcp_echoserver_send(tpcb, es);
- }
- else
- {
- struct pbuf *ptr;
- ptr = es->p;
- pbuf_chain(ptr,p);
- }
- ret_err = ERR_OK;
- }
- else if(es->state == ES_CLOSING)
- {
- /* odd case, remote side closing twice, trash data */
- tcp_recved(tpcb, p->tot_len);
- es->p = NULL;
- pbuf_free(p);
- ret_err = ERR_OK;
- }
- else
- {
- tcp_recved(tpcb, p->tot_len);
- es->p = NULL;
- pbuf_free(p);
- ret_err = ERR_OK;
- }
- return ret_err;
- }
- static void tcp_echoserver_error(void *arg, err_t err)
- {
- struct tcp_echoserver_struct *es;
- LWIP_UNUSED_ARG(err);
- es = (struct tcp_echoserver_struct *)arg;
- if (es != NULL)
- {
- /* free es structure */
- mem_free(es);
- }
- }
- static err_t tcp_echoserver_poll(void *arg, struct tcp_pcb *tpcb)
- {
- err_t ret_err;
- struct echoserver *es;
- es = (struct echoserver *)arg;
- if (es != NULL)
- {
- if (es->p != NULL)
- {
- tcp_sent(tpcb, tcp_echoserver_sent);
- /* there is a remaining pbuf (chain) , try to send data */
- tcp_echoserver_send(tpcb, es);
- }
- else
- {
- /* no remaining pbuf (chain) */
- if(es->state == ES_CLOSING_SERVER)
- {
- /* close tcp connection */
- tcp_echoserver_connection_close(tpcb, es);
- }
- }
- ret_err = ERR_OK;
- }
- else
- {
- /* nothing to be done */
- tcp_abort(tpcb);
- ret_err = ERR_ABRT;
- }
- return ret_err;
- }
- static err_t tcp_echoserver_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
- {
- struct echoserver *es;
- LWIP_UNUSED_ARG(len);
- es = (struct echoserver *)arg;
- es->retries = 0;
- if(es->p != NULL)
- {
- /* still got pbufs to send */
- tcp_sent(tpcb, tcp_echoserver_sent);
- tcp_echoserver_send(tpcb, es);
- }
- else
- {
- /* if no more data to send and client closed connection*/
- if(es->state == ES_CLOSING_SERVER)
- tcp_echoserver_connection_close(tpcb, es);
- }
- return ERR_OK;
- }
- static void tcp_echoserver_send(struct tcp_pcb *tpcb, struct echoserver *es)
- {
- struct pbuf *ptr;
- err_t wr_err = ERR_OK;
- while ( (wr_err == ERR_OK) &&
- (es->p != NULL) &&
- (es->p->len <= tcp_sndbuf(tpcb)))
- {
- /* get pointer on pbuf from es structure */
- ptr = es->p;
- /* enqueue data for transmission */
- wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 1);
- if (wr_err == ERR_OK)
- {
- u16_t plen;
- u8_t freed;
- plen = ptr->len;
- /* continue with next pbuf in chain (if any) */
- es->p = ptr->next;
- if(es->p != NULL)
- {
- /* increment reference count for es->p */
- pbuf_ref(es->p);
- }
- /* chop first pbuf from chain */
- do
- {
- /* try hard to free pbuf */
- freed = pbuf_free(ptr);
- }
- while(freed == 0);
- /* we can read more data now */
- tcp_recved(tpcb, plen);
- }
- else if(wr_err == ERR_MEM)
- {
- /* we are low on memory, try later / harder, defer to poll */
- es->p = ptr;
- }
- else
- {
- /* other problem ?? */
- }
- }
- }
- static void tcp_echoserver_connection_close(struct tcp_pcb *tpcb, struct echoserver *es)
- {
- /* remove all callbacks */
- tcp_arg(tpcb, NULL);
- tcp_sent(tpcb, NULL);
- tcp_recv(tpcb, NULL);
- tcp_err(tpcb, NULL);
- tcp_poll(tpcb, NULL, 0);
- /* delete es structure */
- if (es != NULL)
- {
- mem_free(es);
- }
- /* close tcp connection */
- tcp_close(tpcb);
- }
我使用这个函数,它可以在从客户端接收到数据时发送并回显它,但是如果我调用 tcp_echoserver_send( newpcb, &es ); 代码的任何地方,无法发送。
我遇到了如下断言,
C:/Works/Projects/ STM32Cube_FW_F2_V1.9.0/Middlewares/Third_Party/LwIP/src/core/tcp_out.c 中第 414 行的断言“tcp_write: invalid pcb”失败
任何帮助将不胜感激,谢谢。
0
|
1个回答
|
|
|