Intro web development
Introdução ao Desenvolvimento Web¶
A web está presente em nosso dia-a-dia e o seu desenvolvimento está relacionado ao processo de criação de sites e aplicações para a internet. Ele envolve uma variedade de disciplinas e tecnologias que permitem a construção de conteúdo interativo e dinâmico que pode ser acessado por usuários através de navegadores web (chrome, safari, firefox...).
Componentes do Desenvolvimento Web¶
Vamos definir alguns personagens que estão presentes no desenvolvimento web, geralmente dividimos em duas áreas principais:
-
Front-end
: Também conhecido como "lado do cliente", refere-se à parte da aplicação web que os usuários veem e interagem. Ele é construído usando 3 principais tecnologias que são executadas no navegador do usuário:HTML
(HyperText Markup Language): É a espinha dorsal de qualquer página web, responsável pela estrutura e pelo conteúdo. HTML define a estrutura básica de uma página, como cabeçalhos, parágrafos, listas e links.CSS
(Cascading Style Sheets): É usado para controlar a apresentação, o layout e o design da página HTML. CSS permite estilizar elementos HTML, definindo cores, fontes, espaçamentos, alinhamentos e muito mais.JavaScript
: É uma linguagem de programação que permite adicionar interatividade e dinamismo às páginas web. Com JavaScript, é possível criar efeitos de animação, validar formulários, realizar operações assíncronas com AJAX e manipular o DOM (Document Object Model).
-
Back-end
: Conhecido como "lado do servidor", é responsável pela lógica de negócios, gerenciamento de banco de dados e servidor da aplicação.As tecnologias comuns usadas no back-end incluem:Linguagens de Programação
: Como Python, Ruby, PHP, Node.js e Java. Essas linguagens são usadas para desenvolver a lógica do servidor, manipular dados e interagir com o banco de dados.Frameworks
: Como Flask e Django para Python, Ruby on Rails para Ruby, Express para Node.js e Spring para Java. Os frameworks fornecem uma estrutura e um conjunto de ferramentas para facilitar o desenvolvimento do back-end, incluindo roteamento de URL, manipulação de requisições e respostas, e integração com bancos de dados.Servidores Web
: Como Apache, Nginx e IIS, que são responsáveis por receber as requisições HTTP dos clientes, passá-las para a aplicação back-end e enviar as respostas de volta ao cliente.
-
Banco de dados
: É o componente que armazena e gerencia os dados da aplicação. Ele é fundamental para qualquer aplicação web que precisa persistir informações, como dados de usuários, conteúdo de páginas ou registros de transações. Os tipos comuns de bancos de dados incluem:Bancos de Dados Relacionais
: Como MySQL, PostgreSQL e SQLite, que organizam os dados em tabelas e usam SQL (Structured Query Language) para consulta e manipulação de dados.Bancos de Dados Não Relacionais (NoSQL)
: Como MongoDB, Cassandra e Redis, que são mais flexíveis em termos de estrutura de dados e são frequentemente usados em aplicações que requerem escalabilidade horizontal e manipulação de grandes volumes de dados.
Dinâmica Cliente-Servidor¶
No coração do desenvolvimento web está o modelo cliente-servidor, uma arquitetura de rede que separa clientes (navegadores) e servidores (onde os sites são armazenados e executados). Quando um usuário acessa um site, o navegador (cliente) envia uma solicitação HTTP ao servidor, que então processa a solicitação e envia de volta os dados necessários (geralmente em forma de HTML, CSS e JavaScript) para o navegador exibir a página web.
refs: - https://www.alura.com.br/artigos/o-que-e-front-end-e-back-end - https://realpython.com/python-sockets/
Progress
Continuar...
Prática, um pouco sobre sockets¶
Sockets são uma abstração de endpoints de comunicação que permitem a troca de dados
entre processos em uma rede
ou entre processos na mesma máquina. Eles são a base para a construção de aplicações de rede, como servidores web, clientes de email, jogos online, entre outros.
Como Utilizar Sockets em Python¶
Python oferece uma biblioteca chamada socket
que fornece uma interface de alto nível para trabalhar com sockets.
Vamos dar uma olhada em algums pontos básicos de como criar um socket em Python:
-
Importar e Criar um Objeto Socket:
- Antes de usar sockets, você deve importar a biblioteca socket e para criar, utilizamos o método
socket.socket()
, especificando otipo de endereço
e oprotocolo de comunicação
:
import socket # Cria um socket TCP/IP sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.AF_INET
: Especifica o domínio do endereço do socket.AF_INET
indica que o socket usará endereços IPv4.socket.SOCK_STREAM
: Especifica o tipo do socket.SOCK_STREAM
indica que o socket será do tipo TCP (Transmission Control Protocol), que é orientado a conexão e fornece um fluxo de bytes confiável.
- Antes de usar sockets, você deve importar a biblioteca socket e para criar, utilizamos o método
-
Vincular o Socket a um Endereço e Porta (Servidor)
- Para um servidor, você precisa vincular o socket a um
endereço IP
e umaporta
para escutar por conexões de entrada:
server_address = ('localhost', 10000) # Endereço e porta do servidor sock.bind(server_address)
bind()
: para associar o socket a um endereço IP e uma porta específico.
- Para um servidor, você precisa vincular o socket a um
-
Escutar por Conexões de Entrada (Servidor)
- Após vincular o socket, o servidor deve escutar por conexões de entrada:
sock.listen()
listen()
: para colocaro socket em modo de escuta, permiti que o socket aceite conexões.
-
Aceitar Conexões (Servidor)
- O servidor pode aceitar uma conexão de um cliente usando o método accept(), que bloqueia a execução até que uma conexão seja estabelecida:
connection, client_address = sock.accept()
accept()
:para aceitar uma conexão de um cliente
-
Estabelecer Conexão (Cliente)
- Para um cliente, você deve estabelecer uma conexão com o servidor especificando o endereço IP e a porta do servidor:
server_address = ('localhost', 10000) # Endereço e porta do servidor sock.connect(server_address)
connect()
: para estabelecer uma conexão com o servidor
-
Enviar e Receber Dados
- Tanto o cliente quanto o servidor podem enviar e receber
bytes
usando os métodos send() e recv(): A comunicação sempre é em bytes, não existe comunicação de string ou int, float... é tudo byte!
- os metodos encode() e decode(): codificá em bytes uma string e decodifica de bytes para string.
# Enviar dados message = 'Olá, mundo!' sock.sendall(message.encode()) # Receber dados data = sock.recv(1024) print(f"Recebido: {data.decode()}")
sendall()
: para enviar dadosrecv()
: para receber dados. O argumento especifica o número máximo de bytes a serem lidos. Retorna os dados recebidos como um objeto de bytes.
- Tanto o cliente quanto o servidor podem enviar e receber
-
Fechar o Socket
- Após a comunicação ser concluída, é importante fechar o socket para liberar os recursos:
sock.close()
close()
: fecha a conexão.
Agora que já temos uma idéia das principais funções, definir uma estrutura de comunicação client-server da seguinte forma:
Progress
Continuar...
Question
Antes de continuar na aula, pense e responda:
- Considerando dois processos que precisam se comunicar usando TCP/IP ou UDP/IP, qual deve ser o primeiro passo para iniciar a comunicação?
Answer
Para iniciar a comunicação, um dos processos deve estar em execução no modo de "escuta" (listening), aguardando uma solicitação de conexão do outro processo. Esse processo em modo de escuta é geralmente chamado de servidor. O outro processo, conhecido como cliente, pode iniciar a comunicação a qualquer momento, estabelecendo uma conexão com o servidor.
Progress
Continuar...
Projeto loop-back¶
Vamos criar um projeto de loopback
cliente-servidor, onde a comunicação entre o cliente e o servidor ocorrerá no mesmo computador, utilizando o endereço de loopback 127.0.0.1
.
Basicamente vai funcionar da seguinte forma:
-
Iniciar o Servidor:
- O servidor será iniciado primeiro e ficará escutando em um endereço IP de loopback (127.0.0.1) em uma porta específica (por exemplo, 65432).
- O servidor criará um socket, vinculará esse socket ao endereço e porta especificados e começará a escutar por conexões de entrada.
-
Conectar o Cliente:
- O cliente será iniciado em seguida e tentará se conectar ao servidor usando
o mesmo endereço de loopback e porta
em que o servidor está escutando. - O cliente criará um socket e usará o método
connect()
para estabelecer uma conexão com o servidor.
- O cliente será iniciado em seguida e tentará se conectar ao servidor usando
-
Comunicação:
- Após a conexão ser estabelecida, o cliente poderá enviar dados ao servidor usando o método
send()
ousendall()
do socket. - O servidor receberá os dados enviados pelo cliente usando o método
recv()
do socket. - O servidor vai responder ao cliente enviando dados recebidos de volta, e o cliente vai receber esses dados.
- Após a conexão ser estabelecida, o cliente poderá enviar dados ao servidor usando o método
-
Encerramento da Conexão:
- O código é encerrado quando a comunicação for concluída.
- O cliente e o servidor fecham seus respectivos sockets para encerrar a conexão.
Criando um Servidor Simples¶
Para criar um servidor
simples usando sockets, você precisa seguir os seguintes passos:
Criar um Socket
: Use o método socket() para criar um objeto de socket.Vincular o Socket a um Endereço e Porta
: Use o método bind() para associar o socket a um endereço IP e uma porta específicos.Colocar o Socket em Modo de Escuta
: Use o método listen() para permitir que o socket aceite conexões.Aceitar uma Conexão
: Use o método accept() para aceitar uma conexão de um cliente.Enviar e Receber Dados
: Use os métodos send() e recv() para enviar e receber dados.
O servidor simples:
import socket
HOST = '127.0.0.1' # Endereço IP do servidor
PORT = 65432 # Porta que o servidor está ouvindo
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
print("Servidor escutando...")
conn, addr = s.accept()
with conn:
print(f"Conectado por {addr}")
while True:
data = conn.recv(1024)
if not data:
break
print(f"Recebido: {data.decode('utf-8')}")
conn.sendall(data)
Criando um Cliente Simples¶
Para criar um cliente
simples que se conecta a um servidor usando sockets, você precisa seguir os seguintes passos:
Criar um Socket
: Use o método socket() para criar um objeto de socket.Conectar o Socket ao Servidor
: Use o método connect() para estabelecer uma conexão com o servidor.Enviar e Receber Dados
: Use os métodos send() e recv() para enviar e receber dados.Fechar o Socket
: Use o método close() para fechar a conexão.
O cliente simples:
import socket
HOST = '127.0.0.1' # Endereço IP do servidor
PORT = 65432 # Porta que o servidor está ouvindo
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
# Codifique a string 'Olá, servidor!' usando UTF-8 antes de enviá-la
mensagem = 'Olá, servidor!'.encode('utf-8')
s.sendall(mensagem)
data = s.recv(1024)
print(f"Recebido: {data.decode('utf-8')}")
Question
Teste e valide o funcionamento do client-server simples. Para isso, siga os seguintes passos:
- Crie uma nova pasta de projeto;
- Crie um arquivo python chamado servidor.py e adicione o código fornecido para o servidor;
- Crie um arquivo python chamado cliente.py e adicione o código fornecido para o cliente;
- Em um terminal, execute o código servidor.py;
- Em um novo terminal, execute o código cliente.py;
- obseve o que aconteceu
Responda as pergutas a seguir para validar seus conhecimentos sobre sockets
Question
Qual dos seguintes métodos é utilizado para vincular um endereço e uma porta a um socket em Python?
-
connect()
-
bind()
-
listen()
-
accept()
Answer
O método bind()
é utilizado para vincular um endereço e uma porta a um socket em Python.
Question
Em uma comunicação cliente-servidor, qual dos seguintes métodos é utilizado pelo servidor para escutar por conexões de entrada?
-
connect()
-
bind()
-
listen()
-
accept()
Answer
O método listen()
é utilizado pelo servidor para escutar por conexões de entrada.
Question
Qual das seguintes alternativas é verdadeira sobre o método accept()
em um servidor de socket?
- Ele é usado para enviar dados para um cliente.
- Ele é usado para receber dados de um cliente.
- Ele é usado para aceitar uma conexão de um cliente.
- Ele é usado para escutar por conexões de entrada.
Answer
O método accept()
é usado por um servidor de socket para aceitar uma conexão de um cliente.
Question
Em uma comunicação de rede usando sockets, qual das seguintes afirmações é verdadeira sobre o endereço IP 127.0.0.1
?
- É usado para se referir a um dispositivo remoto na rede.
- É o endereço de loopback que se refere ao próprio dispositivo.
- É o endereço IP padrão para todos os roteadores.
- É um endereço IP reservado para uso futuro.
Answer
O endereço IP 127.0.0.1
é conhecido como endereço de loopback e é usado para se referir ao próprio dispositivo na rede.
Progress
Continuar...
Projeto WebChat via socket¶
Legal, agora que já conhecemos e sabemos criar uma conexão socket, vamos avançar criando uma aplicação Client-Server por meio de um chat usando sockets. Basicamente, esse novo sistema consiste de um servidor que gerencia as mensagens de multiplos clientes conectados.
Question
- Clone o repositório.
git clone https://github.com/arnaldojr/client-server.git
cd client-server
- Inicie
primeiramente
o servidor, nesse caso será o pc do professor será o HOST:
python server.py
- Em outro terminal, inicie um ou mais clientes. Neste caso é importante ajustar o IP do Host:
python client.py
- Digite seu nome de usuário e comece a enviar mensagens 😁. Para sair do programa, digite "sair".