Para manipularmos um arquivo ASCII no Python, fazemos assim:
arquivo = open("cadastro.txt", "w")
"""
w - Write (escrever)
a - Append (acrescentar)
r - Read (ler)
"""
Caso o arquivo cadastro.txt exista, ao usar o w
ele sobrescreverá, para adicionar usamos a opção a
, e o r
é usado para ler o arquivo.
Podemos fazer esse programa para criar um arquivo:
nome = str(input("Digite seu nome: "))
idade = int(input("Digite sua idade: "))
sexo = str(input("Digite seu sexo: "))
arquivo = open("cadastro.txt", "w")
arquivo.write("-" * 30)
arquivo.write("\n")
arquivo.write(f"Nome: {nome}\n")
arquivo.write(f"Idade: {idade}\n")
arquivo.write(f"Sexo: {sexo}\n")
arquivo.close()
print("\nArquivo cadastro criado com sucesso!")
No caso acima, ele sobrescreverá, para adicionar algo no arquivo, usamos a opção a
.
Para ler o mesmo arquivo, basta isso:
arquivo = open("cadastro.txt", "r")
print(arquivo.read())
arquivo.close()
Podemos jogar o conteúdo em variáveis, veja um exemplo simples:
arquivo = open("cadastro.txt", "r")
conteudo = arquivo.read()
nome = conteudo.split("Nome: ")[1].split("\n")[0]
idade = int(conteudo.split("Idade: ")[1].split("\n")[0])
sexo = conteudo.split("Sexo: ")[1].split("\n")[0]
arquivo.close()
print(nome)
print(idade)
print(sexo)
PS: Podemos colocar isso num for para ler todos os nomes descritos no arquivo, já que este código só pega o primeiro cadastro.
Como sabemos, podemos trabalhar com dicionários em Python, que permite trabalhar com nomes literais nos índices do mesmo, como por exemplo:
cadastro = dict()
cadastro["nome"] = str(input("Digite seu nome: "))
cadastro["idade"] = int(input("Digite sua idade: "))
cadastro["sexo"] = str(input("Digite seu sexo: "))
print(cadastro)
Sabendo disso, podemos transformar esse dicionário num JSON:
import json
cadastro = dict()
cadastro["nome"] = str(input("Digite seu nome: "))
cadastro["idade"] = int(input("Digite sua idade: "))
cadastro["sexo"] = str(input("Digite seu sexo: "))
cadJson = json.dumps(cadastro)
print(cadJson)
E da mesma forma, podemos salvar num arquivo com a extensão JSON, igual fizemos com o arquivo de texto:
import json
cadastro = dict()
cadastro["nome"] = str(input("Digite seu nome: "))
cadastro["idade"] = int(input("Digite sua idade: "))
cadastro["sexo"] = str(input("Digite seu sexo: "))
cadJson = json.dumps(cadastro)
arquivo = open("cadastro.json", "w")
arquivo.write(cadJson)
arquivo.close()
print("\nArquivo JSON escrito com sucesso!")
Da mesma forma, podemos ler um JSON assim:
import json
arquivo = open("cadastro.json", "r")
cadJson = json.loads(arquivo.read())
arquivo.close()
print(cadJson)
E podemos melhorar esse código, assim:
import json
arquivo = open("cadastro.json", "r")
cadJson = json.loads(arquivo.read())
arquivo.close()
nome = str(cadJson["nome"])
idade = int(cadJson["idade"])
sexo = str(cadJson["sexo"])
print(f"Nome: {nome}")
print(f"Idade: {idade}")
print(f"Sexo: {sexo}")
Como sabemos, o Netcat é um programa no qual podemos ler e escrever dados através de conexões utilizando os protocolos TCP ou UDP. Sabendo de como ele funciona, podemos criar nosso servidor TCP e comunicar com ele através do Netcat. Para ele aguardar uma conexão, basta digitar nc -lvp 8080, que ele escutará o endereço 0.0.0.0 (que pode escutar qualquer IP que represente sua própria máquina).
Para trabalhar com TCP/IP, usaremos a biblioteca socket do Python, para criar nosso próprio servidor. Podemos fazer nosso código assim, por exemplo:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
""""
AF_INET = IPv4
AF_INET6 = IPv6
SOCK_STREAM - TCP
SOCK_DGRAM - UDP
"""
Como visto AF_INET é para IPv4 e AF_INET6 para IPv6. Da mesma forma, SOCK_STREAM é para TCP e SOCK_DGRAM é para UDP.
Para criar um servidor simples, podemos fazer assim:
import socket
ip = "0.0.0.0"
porta = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((ip, porta))
sock.listen(1) # Quantidade de conexões que serão aguardadas
print(f"Aguardando conexão {ip}:{porta}...")
sock.accept()
Rode primeiro o servidor acima, e no terminal digite nc 127.0.0.1 8080 (que será nosso cliente). O servidor aceitará a conexão.
Para um poder mandar mensagem pro outro, podemos fazer assim, alterando o sock.accept() e abaixo dele:
conn, cliente = sock.accept() # A função retorna dois valores, um pra cada variável.
print(f"Conectado com {cliente}.") # Mostrará o endereço do cliente
msg = input("> ")
msg += "\n"
conn.send(msg.encode()) # Transforma string em bytes e envia pro cliente.
dados = conn.recv(1024) # Buffer com a quantidade de informações em bytes a receber
Rode o servidor e depois rode o comando no Netcat. Ele se comunicará, mas cairá em seguida.
PS: Apesar de configurado, costuma dar erros ao transmitir e receber textos com acentuação.
Para ele ficar num loop infinito, podemos colocar o while assim:
while True:
msg = input("> ")
msg += "\n"
conn.send(msg.encode()) # Transforma string em bytes e envia pro cliente.
dados = conn.recv(1024) # Buffer com a quantidade de informações em bytes a receber
print(dados.decode(), end = "")
Podemos inclusive pedir uma senha que aparecerá no Netcat para conexão, colocando isso abaixo do print de conectado:
conn.send("Digite a senha: ".encode())
senha = conn.recv(1024)
if senha.decode().strip() == "senhafoda":
while True:
msg = input("> ")
if msg == "sair":
conn.send(f"Servidor encerrando conexão com {cliente}...".encode())
sock.close()
break
msg += "\n"
conn.send(msg.encode()) # Transforma string em bytes e envia pro cliente.
dados = conn.recv(1024) # Buffer com a quantidade de informações em bytes a receber
print(dados.decode(), end = "")
else:
conn.send("Senha Incorreta!".encode())
sock.close()
O cliente é bem mais simples que o servidor. Da mesma forma, criaremos um socket simples assim:
import socket
ip = "127.0.0.1"
porta = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, porta))
msg = sock.recv(1024).decode()
senha = input(msg)
sock.send(senha.encode())
while True:
print(sock.recv(1024).decode(), end = "")
msg = input("> ")
msg += "\n"
sock.send(msg.encode())
Rode o servidor primeiro e depois o cliente.
PS: No servidor, podemos colocar parâmetros para serem passados pelo terminal, como por exemplo:
import socket
import sys
ip = "0.0.0.0"
porta = int(sys.argv[1])
Daí é só passar rodando o script com o python3 ServidorTCP.py 8080 (ou a porta desejada).
E no cliente também podemos fazer assim:
import socket
import sys
ip = sys.argv[1]
porta = int(sys.argv[2])
Da mesma forma, é só passar rodando o script com o python3 ClienteTCP.py 127.0.0.1 8080 (ou o IP e a porta desejada).
O servidor e o cliente UDP são mais simples que os em TCP, já que o UDP é mais rápido e não estabelece conexões.
Veja um exemplo simples de servidor UDP:
import socket
porta = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("0.0.0.0", porta))
print(f"Aguardando conexão UDP 0.0.0.0:{porta}.")
while True:
dados, cliente = sock.recvfrom(1024) # Também retorna dois valores
print(f"{cliente} - {dados.decode()}")
msg = input("> ")
sock.sendto(msg.encode(), cliente)
Como o UDP não precisa estabelecer conexões, qualquer dispositivo pode se conectar ao servidor, que enviará a informação pro cliente.
Veja o exemplo do cliente UDP:
import socket
ip = "127.0.0.1"
porta = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
msg = input("> ")
sock.sendto(msg.encode(), (ip, porta))
dados, serv = sock.recvfrom(1024)
print(f"{serv} - {dados.decode()}")
PS: Observe que não tem a função connect nesse caso, porque o UDP é orientado a datagrama, diferente do TCP, que é orientado a conexão.
Rode o servidor primeiro, e depois o cliente.