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