so if you look into my post history you will know that I have been trying a project in TCP using LwIP. I was unable to capture data in the server side, but now I have resolved that issue. But now I have a new one.
I connect to the TCP server(STM32-nucleo-144) and the wireshark shows the three-way-handshake happening between the server and the client, then I send messages to the server and the server responds as per the programming, now I terminate the connection on the client side, the client sends a packet with [FIN,ACK] flags set, but the server never responds back with a [FIN,ACK]. I use an App for TCP transmission called hercules, when I press 'disconnect' it displays the message connection closed when it never really happened as it can be seen from wireshark.
I also used another app to check, this app sends TCP packets continuously at predefined intervals, it creates a connection, sends packets, accepts a response then closes the connection, and after the interval it repeats this process again. When I started this app, the first connection was created, data was sent and received by the client, the [FIN,ACK] flags were sent by the client but no response from server from there on.
I did a ping test, it seems the server becomes unreachable as soon as the disconnect starts.
Here is my code:-
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_LWIP_Init();
/* USER CODE BEGIN 2 */
IP_ADDR4(&myIPADDR,192,168,33,2);
IP_ADDR4(&destip,192,168,33,101);
tcp_pcb = tcp_new();
err_t err = tcp_bind(tcp_pcb, &myIPADDR, 4100);
if(err == ERR_OK)
{
tcp_pcb = tcp_listen_with_backlog(tcp_pcb, 2);
tcp_accept(tcp_pcb, tcp_echoserver_accept);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
ethernetif_input(&gnetif);
sys_check_timeouts();
}
/* USER CODE END 3 */
}
err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
tcp_arg(tcp_newpcb, tcp_newpcb);
tcp_recv(newpcb, recv_callback);
return ERR_OK;
}
err_t recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
sprintf(data, "this is the message: '%s'", p->payload);
tcp_recved(tpcb, p->len);
tcp_write(tpcb, data,p->len+23, 0x02);
pbuf_free(p);
err = ERR_OK;
return err;
}
Here is what is shown is wireshark after i press the disconnect butotn in hercules
13366 6286.571000 192.168.33.101 192.168.33.2 TCP 54 52649 → 4100 [FIN, ACK] Seq=12 Ack=35 Win=65358 Len=0
13367 6286.883778 192.168.33.101 192.168.33.2 TCP 54 [TCP Retransmission] 52649 → 4100 [FIN, ACK] Seq=12 Ack=35 Win=65358 Len=0
13369 6287.498291 192.168.33.101 192.168.33.2 TCP 54 [TCP Retransmission] 52649 → 4100 [FIN, ACK] Seq=12 Ack=35 Win=65358 Len=0
13371 6288.709492 192.168.33.101 192.168.33.2 TCP 54 [TCP Retransmission] 52649 → 4100 [FIN, ACK] Seq=12 Ack=35 Win=65358 Len=0
13374 6291.112720 192.168.33.101 192.168.33.2 TCP 54 [TCP Retransmission] 52649 → 4100 [FIN, ACK] Seq=12 Ack=35 Win=65358 Len=0
In your receive callback, you have to check if the pbuf pointer p is NULL
in which case, the connection was closed at the other end and you need to call tcp_close
. The reason why the server becomes unreachable is because you are dereferencing a NULL pointer, which would trigger a hard fault.