首页 > 解决方案 > 使用python中已经打开的套接字发送数据

问题描述

我构建了一个小程序来监听任意连接并处理它们的请求,将事件和连接信息保存到 sqlite 数据库。一旦连接关闭并再次打开,它就会更新源端口。

这就像一个魅力,但现在我希望能够随机发送这些主机消息,并且我无法打开与它们的新连接,因为它们可能位于 NAT 后面。

有没有办法利用已经打开的连接来传输数据?我的意思是,我可以在thread_cliente's while True 中编写一个函数,用于检查数据库中是否有要传递给它的消息,但我认为必须有一种更简单或更优雅的方法来完成它。

下面是我的套接字服务器代码。我将我的评论从葡萄牙语翻译成英语。不幸的是,我的同事坚持使用葡萄牙语变量,所以这可能会引起一些混乱。

#!/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()

标签: pythonpython-3.xsockets

解决方案


在原始套接字上发回可能是与客户端交谈的最佳方式。

如果您不担心客户端数量过多,您可以保持客户端连接打开直到您需要它,并将套接字保存在某个地方以备后用。


推荐阅读