一般来说,对于套接字编程和线程来说相当新,我的问题可能源于对它们如何工作的误解。我正在尝试使用线程创建充当客户端和服务器的东西。
下列的程序: 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的套接字来发送消息(即时消息)。这些插座是留下来关闭的,因为它们实际上不负责接收任何东西。
我很感激我能得到的任何帮助。
答案 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)
顺便说一句,我已经取得了一些突破。虽然我并不完全确定为什么它会这样做,但是为了这个目的,threadsTCPServer(因为它在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)
中看到的解决方案调整了此代码我必须重新编写大部分代码,但我认为它确实有效,我会在实施后报告。