Я создал небольшую программу, которая прослушивает произвольные соединения и обрабатывает их запросы, сохраняя информацию о событиях и соединениях в базе данных sqlite. Как только соединение закрывается и открывается снова, оно обновляет порт источника.
Это работает как чудо, но теперь я хочу иметь возможность произвольно отправлять сообщения этих хостов, и я не могу открыть новые соединения для них, потому что они могут быть позади NAT.
Есть ли способ использовать уже открытые соединения для передачи данных? Я имею в виду, что я мог бы написать функцию в thread_cliente
, в то время как True, которая проверяет, есть ли в базе данных сообщение для его доставки, но я решил, что должен быть более простой или более элегантный способ сделать это.
Ниже мой код для сокет-сервера. Я перевел свои комментарии с португальского на английский sh. К сожалению, мои коллеги настаивают на использовании португальских переменных, так что это может вызвать некоторую путаницу.
#!/usr/bin/env python3
import socket
import sys
import logging
from _thread import start_new_thread
from MyPack import all_my_stuff
def print_help():
print(f'{sys.argv[0]} [TCP Port] [Someting that my program do]')
sys.exit()
def start_server(porta):
servico = socket.socket()
try:
servico.bind(('', porta))
except socket.error as e:
logging.error(e)
servico.listen(1024) # Is 1024 the max simultaneous client number?
while True:
cliente, endereco = servico.accept()
logging.debug(
f'New connection {endereco[0]}:{endereco[1]}'
)
try:
start_new_thread(thread_cliente, (cliente, endereco, ))
except Exception as e:
logging.error(e)
servico.close()
def thread_cliente(conexao, endereco):
while True:
data = conexao.recv(128)
if data:
resposta = None
sibulla_db.insere_conexao(endereco[0], endereco[1], sys.argv[1])
resposta = all_my_stuff.do_something(data, sys.argv[1], endereco)
if resposta:
logging.debug(f'Sending data: {resposta}')
conexao.sendall(bytes.fromhex(resposta))
else:
# Close connection
logging.debug(
f'Connection closed {endereco[0]}:{endereco[1]}'
)
break
conexao.close()
def main():
if len(sys.argv) == 1 or sys.argv[1] == 'help':
# are you running it right, or asking for help
print_help()
# Log
logging.basicConfig(
format='%(asctime)s %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
filename='sibulla.log',
level=logging.DEBUG
)
# Start it
start_server(int(sys.argv[1]))
if __name__ == '__main__':
main()