Buscar

Redes de computadores

Prévia do material em texto

UFJF
UNIVERSIDADE FEDERAL DE JUIZ DE FORA
Redes de Computadores
Aluno: Gabriel Martins Quintana Vieira Marques (201835009)
Professor: Alex Borges Vieira
1) Descrição do trabalho
Esse trabalho foi feito com intuito de desenvolver um protocolo
cliente-servidor utilizando threads. Um servidor multithread é um servidor que
manipula múltiplas requisições de forma simultânea e em paralelo. No nosso
caso o servidor irá permitir que vários clientes possam se conectar ao mesmo
tempo a um único servidor.
Neste documento em diante irei mostrar todo o processo de desenvolvimento
que eu segui e também como implementei esse problema.
2) Tomada de decisões
O trabalho foi desenvolvido utilizando a linguagem de programação Python
devido a extensa documentação existente e suas inúmeras aplicações. É uma
linguagem de fácil aprendizado e possui uma vasta comunidade em ascensão.
Para a questão do código em si, foram utilizadas somente as bibliotecas de
socket, threading e colorama. A biblioteca socket foi utilizada para fazer o
protocolo cliente servidor com o módulo socket. Threading foi utilizada para
tornar o servidor multithread e colorama foi usado para facilitar a leitura do
usuário com diferentes cores de print no terminal.
3) Estruturação do trabalho
Antes de começar a falar da estruturação do trabalho, gostaria de dizer que
resumi um pouco a explicação aqui porque expliquei de forma mais detalhada
no vídeo enviado.
Dito isso para entender melhor a estruturação do trabalho é importante citar
primeiramente que o código foi dividido em dois arquivos diferentes, um deles
é o arquivo client.py onde está o código da parte do cliente, e o outro é o
arquivo server.py onde está o código da parte do servidor.
Client.py
Para o código do cliente não utilizei classes. Criei variáveis de IP e PORT(Porta)
e pedi como input para o usuário conectar ao respectivo servidor com esses
valores. Utilizei um loop para manter o usuário conectado e podendo escrever
mensagens para o servidor enquanto ele não digitasse o comando quit.
Coloquei também mensagens de erro caso o usuário digite um comando
errado.
Server.py
Para o código do servidor utilizei a classe handle_client que é a classe que será
responsável por lidar com a parte do cliente (comandos, decodificação, entre
outros) enquanto o mesmo estiver conectado. Utilizei também um loop para
permitir que o servidor continue aceitando clientes enquanto estiver
conectado, nesse loop também temos a utilização da thread que é de extrema
importância e será responsável por permitir que o servidor comporte mais de
um cliente ao mesmo tempo.
4) Entrada e saída
Entrada
As entradas são feitas ao lado do cliente (ao rodar o arquivo client.py) é pedido
para que ele digite o IP e o PORT(Porta) do Host(servidor) que ele deseja se
conectar.
Saída
No caso da minha implementação, como não foi pedido, não coloquei
nenhuma saída. Tudo é feito no terminal.
5) Como utilizar o programa
Instalação
Para utilizar o programa é bem fácil.
● É necessário instalar o python na máquina que irá realizar os testes. Para
isso é preciso que o usuário tenha acesso a internet e possa acessar o
site https://www.python.org/downloads para baixá-lo. O usuário deverá
https://www.python.org/downloads/
verificar qual o Sistema Operacional de sua máquina, a versão do python
desejada (no caso em questão foi utilizado o python3) e seguir a
orientação descrita no site para continuar com a instalação.
● Foi utilizado a biblioteca colorama, caso o usuário tenha algum
problema é importante verificar o site https://pypi.org/project/colorama/
e seguir os passos, realizando a instalação das dependências.
● Após baixar o python e verificar as bibliotecas utilizadas, o usuário deve
baixar os arquivos client.py e server.py.
Após todos esses passos, e com o client.py e server.py em seu computador, o
usuário poderá começar a utilizar o programa.
Utilização
Para a utilização temos os seguintes passos.
1)Abrir o terminal clicando com o botão direito na pasta que está o arquivo
server.py, e digitar no terminal que foi aberto o comando “python3 server.py”
https://pypi.org/project/colorama/
2)Após o passo 1 o servidor foi iniciado, agora o usuário deve deixar esse
terminal aberto, e abrir outro na mesma pasta e rodar o comando “client.py”.
3) Pronto o usuário foi conectado e já pode enviar mensagens para o servidor.
Os comandos para o usuário estão descritos no terminal. Caso ele queira
mandar uma mensagem para o servidor ele deve digitar o comando echo
<mensagem>. Já se ele quiser finalizar a conexão com servidor ele deve digitar
o comando echo <quit>.
Se o usuário não colocar o comando echo antes das mensagens o servidor
nem irá recebê-las.
6) Código fonte
Cliente
import socket
from colorama import Fore, Back, Style
IP = input("Digite o IP do servidor -> ")
PORT = input("Digite a porta do servidor -> ")
PORT = int(PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((IP,PORT))
print('\033[32m' +
f"Você se conectou no servidor" + '\033[39m')
print('\033[35m' +
f"{Style.BRIGHT}Como usar o servidor:" + '\033[39m')
print('\033[35m' +
f"{Style.BRIGHT}-> echo 'mensagem' [para digitar uma mensagem]" +
'\033[39m')
print('\033[35m' +
f"{Style.BRIGHT}-> quit [para finalizar sua conexão]" +
'\033[39m')
connected = True
while connected:
message = input(">>> ")
if (message.startswith("echo") or message == "quit"):
client.send(message.encode("utf-8"))
if (message == 'quit'):
print('\033[31m' + 'Você foi desconectado!' + '\033[39m')
connected = False
else:
message = client.recv(1024).decode("utf-8")
print('\033[36m' +
f"{Style.BRIGHT}[Resposta do servidor] {message}" +
'\033[39m')
else:
print('\033[33m' +
f"{Style.BRIGHT}[Erro de digitação] Verifique novamente
como usar o servidor!" + '\033[39m')
Servidor
import socket
import threading
from colorama import Fore, Back, Style
IP = ""
PORT = 4445
def handle_client(connection, address):
print('\033[32m' +
f"[Nova conexão] Endereço {address} conectado no servidor." +
'\033[39m')
connected = True
while connected:
message = connection.recv(1024).decode("utf-8")
splitmessage = message.split(" ")
new_message = ""
for value in splitmessage:
if(value != 'echo'):
new_message += value + " "
if message == 'quit':
connected = False
print(f"[{address}] {new_message}")
if(connected == False):
print('\033[31m' +
f"Usuário {address} foi desconectado!" + '\033[39m')
connection.send(new_message.encode("utf-8"))
connection.close()
print("[INICIANDO] Servidor está iniciando")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((IP, PORT))
server.listen()
print(
'\033[36m' + f"[ESCUTANDO] Servidor está escutando" + '\033[39m')
while True:
connection, address = server.accept()
thread = threading.Thread(target=handle_client, args=(connection,
address))
thread.start()
print(
'\033[35m' + f"[CONEXÕES ATIVAS] {threading.activeCount() - 1}"
+ '\033[39m')
7) Testes
Além do vídeo disponibilizado nos arquivos que eu enviei, resolvi dar uma
complementada, e acabei por realizar 4 testes distintos (porque não deu
tempo de fazer mais).
O primeiro foi para testar o que acontece caso eu feche o servidor com um
cliente conectado. No caso a primeira mensagem não tem resposta do
servidor, porém continua conectado. Já na segunda mensagem temos um
erro de BrokenPipeError. Isso acontece porque o processo de leitura (head) é
finalizado e o processo de escrita (python) ainda tenta escrever, o que
ocasiona em erro.
O segundo foi para testar o que aconteceria caso eu conectasse o servidor
com o IP de localhost em uma virtualbox que não está rodando o servidor. O
resultado é que não conseguimos conectar nesse servidor, e ainda recebemos
o erro de Connection Refused. Esse erro significa que, por qualquer motivo, o
cliente não pode se conectar à porta no computador que está executando o
script do servidor.
O terceiro foi para testar o que aconteceria caso eu tentasse conectar no
servidorcom uma porta diferente da que foi setada. O resultado foi o mesmo
obtido no teste 2 (ConnectionRefusedError) e no caso de uma porta que não
está entre o limite 0-65535 obtivemos como resposta o erro OverflowError.
O quarto eu quis criar vários clientes para testar se o servidor continuaria apto
a escutar todos eles. Acabei então por criar 30 e funcionou perfeitamente,
imagino que provavelmente daria para ligar ainda mais clientes no servidor,
mas é muito provável que tenha um limite (talvez ligado à memória RAM?
Meu computador tem 32GB de RAM então só se eu fizesse um script eu
conseguiria descobrir esse limite).
Também é importante notar que se eu fechar a aba que estão esses terminais
Todos eles estarão desconectados do servidor.
8) Referências:
Vídeo que usei para aprender a fazer o NAT Network
https://www.youtube.com/watch?v=vReAkOq-59I&t=180s&ab_channel=AlpineS
ecurity
Biblioteca usada do colorama
https://pypi.org/project/colorama/
https://www.youtube.com/watch?v=vReAkOq-59I&t=180s&ab_channel=AlpineSecurity
https://www.youtube.com/watch?v=vReAkOq-59I&t=180s&ab_channel=AlpineSecurity
https://pypi.org/project/colorama/

Continue navegando