永远在后台运行python线程TCP服务器

时间:2017-04-12 15:43:27

标签: python multithreading sockets tcp server

一般来说,对于套接字编程和线程来说相当新,我的问题可能源于对它们如何工作的误解。我正在尝试使用线程创建充当客户端和服务器的东西。

下列的程序: https://docs.python.org/3/library/socketserver.html#asynchronous-mixins

我创建了一个客户端类来与服务器一起使用并从主类执行。服务器应该正常启动并且不会出现任何错误,但是当我尝试从客户端连接时,它会在以下情况下失败:

    # In client connection
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.connect((ip, port))

我得到的错误是:

Traceback (most recent call last):
  File "./<project>", line 61, in <module>
    client.start_client(serverInfo)
  File "/home/<username>/Documents/Github/project/client.py", line 54, in <startclient>
    <connectionMethod>(cmd)
  File "/home/<username>/Documents/Github/project/client.py", line 112, in <connectionMethod>
    sock.connect((remoteHOST,remotePORT))
    ConnectionRefusedError: [Errno 111] Connection refused

即使我从引用的python页面中的代码修改服务器(只是在特定端口上运行,1234),并尝试使用

连接到该端口
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.connect(('127.0.0.1',1234))
    sock.sendall('Test message')

我遇到同样的问题

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ConnectionRefusedError: [Errno 111] Connection refused

为什么服务器拒绝连接?没有防火墙规则或iptables,运行具有客户端和套接字的示例,因为从站点起作用,但即使删除server.shutdown()行,它仍然会立即自杀。

我错过了什么吗?

我期待的行为是:

./programA
<server starts on port 30000>

./programB
<server starts on port 30001>
<client starts>

---输入/输出---

FROM CLIENT A:

/connect 127.0.0.1 30001
CONNECTED TO 127.0.0.1 30001

ON CLIENT B:

CONNECTION FROM 127.0.0.1 30000

基本上,一旦客户端第一次连接,他们就可以通过键入一个提示符来相互通信,该提示符只是创建另一个针对“远程”IP和PORT的套接字来发送消息(即时消息)。这些插座是留下来关闭的,因为它们实际上不负责接收任何东西。

我很感激我能得到的任何帮助。

2 个答案:

答案 0 :(得分:0)


甚至删除server.shutdown()没有帮助的原因是因为当主线程存在时,服务器线程立即存在,因为您可能尚未删除server_thread.daemon=True
如果你将它改为server_thread.daemon=False,那么即使在主线程终止后,程序也不会立即返回终端,但即使在主程序的最后一行被执行后也不会终止服务器。我不确定你是否可以使用简单的python脚本在后台完全运行服务器,但我不认为这是可能的。

你可以用'&amp;'来调用脚本选项:python3 <file>.py &将在后台运行python脚本(这至少适用于Ubuntu)(https://askubuntu.com/questions/396654/how-to-run-the-python-program-in-the-background-in-ubuntu-machine)但它可能不是您正在寻找的答案。

答案 1 :(得分:0)

顺便说一句,我已经取得了一些突破。虽然我并不完全确定为什么它会这样做,但是为了这个目的,threadsT​​CPServer(因为它在python docs上)基本上是不可用的,并且在实际上在一个线程中不会正确行动。相反,我选择手动构建一个套接字服务器,如下所示:

import threading
import socket

def simpleServer():
    HOST = '127.0.0.1'
    PORT = 3000
    sock = socket.socket()
    sock.bind((HOST,PORT))

    s.listen(5)
    while True:
        conn, addr = s.accept()
        msg = str(conn.recv(1024),'utf8')
        c.send(bytes('GOT: {0}'.format(msg),'utf8')
        c.close()

if __name__ == '__main__':

    server_thread = threading.Thread(target=simpleServer)
    server_thread.start()

    # Make connections based on '<ip>:<port>:<msg>'
    while True:
        cmd = input('>> ')

        try:
            parts = cmd.split(':')
            ip = parts[0]
            port = parts[1]
            msg = parts[2]

            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
                sock.connect((ip,port))
                sock.sendall(bytes(msg,'utf8'))
                print(str(sock.recv(1024),'utf8'))

        except Exception as e:
            print(e)

代码是非常基本的(可能不是最好的),但我刚刚测试过它,它现在肯定是有效的。我根据我在Why am I getting the error "connection refused" in Python? (Sockets)

中看到的解决方案调整了此代码

我必须重新编写大部分代码,但我认为它确实有效,我会在实施后报告。