O próximo passo do estudo é brincar um pouco com comunicação TCP. No pico-examples tem exemplos do client e do server, usando a mesma estrutura esquisita do exemplo de NTP. Vamos ver se conseguimos entender o que é feito.
TCP Client
O código pode ser visto em https://github.com/raspberrypi/pico-examples/blob/master/pico_w/tcp_client/picow_tcp_client.c
Como no UDP, o estado da comunicação é guardado em uma estrutura "pcb" (no caso tcp_pcb). A criação desta estrutura, o cadastro dos callbacks é o disparo da conexão estão na rotina tcp_client_open:
// Versão simplificada e comentada static bool tcp_client_open(void *arg) { // cria o PCB (Protocol Control Block) state->tcp_pcb = tcp_new_ip_type(IP_GET_TYPE(&state->remote_addr)); // Define o argumento que será passado aos callbacks tcp_arg(state->tcp_pcb, state); // Define um callback chamado perioridamente tcp_poll(state->tcp_pcb, tcp_client_poll, POLL_TIME_S * 2); // Define um callback chamado quando um transmissão foi confirmada pelo receptor tcp_sent(state->tcp_pcb, tcp_client_sent); // Define um callback chamado quando dados são recebidos tcp_recv(state->tcp_pcb, tcp_client_recv); // Define um callback chamado quando ocorre um erro fatal tcp_err(state->tcp_pcb, tcp_client_err); // Dispara a conexão, tcp_client_connected é chamado se e quando a conexão // tiver sucesso cyw43_arch_lwip_begin(); err_t err = tcp_connect(state->tcp_pcb, &state->remote_addr, TCP_PORT, tcp_client_connected); cyw43_arch_lwip_end(); return err == ERR_OK; }
Ok, dá para entender. O funcionamento todo da comunicação TCP é através de callbacks , com o lwIP chamando as suas rotinas quando algo acontece. Vamos ver o que cada um dos callbacks faz:
- tcp_client_poll(): só faz um print para dizer que foi chamada.
- tcp_client_err(): imprime uma mensagem de erro
- tcp_client_connected(): atualiza o estado da aplicação para esperar o server enviar algo.
- tcp_client_recv(): recebe os dados e, opcionalmente, os imprime. É necessário chamar tcp_recved() para confirmar o recebimento. Os dados são enviados de volta ao servidor, através de tcp_write().
- tcp_client_sent(): verifica se o teste foi concluído, se não volta a aguardar dados
TCP Server
A iniciação do server (em tcp_server_open) é composta por chamadas a:
- tcp_bind() para indicar qual porta será TCP monitorada
- tcp_listen_with_backlog(): prepara para receber conexões, devolve um pcb específica para isso. As chamadas serão colocadas em uma fila (no caso com apenas uma posição)
- tcp_accept(): aguarda receber uma conexão e define a rotina que será chamada quando isso acontecer.
Nenhum comentário:
Postar um comentário