这不是connection refused的重复。此问题询问MacOS
和Windows
之间的区别。此外,Mac
上的防火墙已关闭。
我正在尝试通过套接字与设备通信。代码用python
编写。出于某种原因,如果我在Windows
上运行我的代码,一切正常,但如果我在Mac
上执行,则不会。我的一位同事在C
中编写了相同的代码,并在Mac
上运行并且没有任何问题。有人知道会出现什么问题吗?
如果需要,我可以提供更多详细信息。请告诉我哪些。
修改
这是代码
class Device(object):
def __init__(self, ip_addr, port):
self.ip_addr = ip_addr
self.port = port
def say_hi(self):
msg = [254, 49, 0]
ret = self.send_msg(msg)
msg = [254, 29]
return self.send_msg(msg)
def say_bye(self):
msg = [254, 49, 0]
ret = self.send_msg(msg)
msg = [254, 30]
return self.send_msg(msg)
def get_status(self):
msg = [254, 49, 0]
ret = self.send_msg(msg)
msg = [254, 16]
return self.send_msg(msg)
def send_msg(self, msg):
msg = ''.join(chr(i) for i in msg)
s = socket.create_connection((self.ip_addr , self.port))
s.sendall(msg)
ret = s.recv(1)
s.close()
return ord(ret)
这是我得到的错误:
[Errno 61] Connection refused
错误发生在以下行:
s = socket.create_connection((self.ip_addr , self.port))
编辑2
ip_addr='172.24.176.46', port='2101'
我可以访问该地址。以下是ping
$ ping 172.24.176.46
PING 172.24.176.46 (172.24.176.46): 56 data bytes
64 bytes from 172.24.176.46: icmp_seq=0 ttl=64 time=0.495 ms
64 bytes from 172.24.176.46: icmp_seq=1 ttl=64 time=0.398 ms
64 bytes from 172.24.176.46: icmp_seq=2 ttl=64 time=0.452 ms
^C
编辑3
我找到了一个有效的代码,它可以在Windows和Mac上运行。我将在下面提供,但基本上我做的是在类初始化期间(即在__init__
)和不关闭send_msg
中的连接时创建连接。这是我的问题:这样做是否安全和正确?不关闭连接似乎不是一个好方法。我很感激任何帮助。我的新代码如下。
class Device(object):
def __init__(self, ip_addr, port):
self.ip_addr = ip_addr
self.port = port
self.socket = socket.create_connection((self.ip_addr , self.port))
def say_hi(self):
msg = [254, 49, 0]
ret = self.send_msg(msg)
msg = [254, 29]
return self.send_msg(msg)
def say_bye(self):
msg = [254, 49, 0]
ret = self.send_msg(msg)
msg = [254, 30]
return self.send_msg(msg)
def get_status(self):
msg = [254, 49, 0]
ret = self.send_msg(msg)
msg = [254, 16]
return self.send_msg(msg)
def send_msg(self, msg):
msg = ''.join(chr(i) for i in msg)
self.socket.sendall(msg)
ret = self.socket.recv(1)
return ord(ret)
答案 0 :(得分:0)
根据我在Mac上的测试,您不能使用相同的套接字来收听。可能有一种方法可以以这种方式使用套接字,如果我建议您阅读 https://docs.python.org/2/howto/sockets.html#socket-howto
我只能使用两个不同的套接字连接python并分别创建客户端和服务器。对于服务器,代码类似于:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('', self.port))
server.listen(1)
connection, client_addr = server.accept()
connection.recv(1024)
connection.close()
server.close()
对于客户端,代码类似于:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
client.connect(('10.6.6.11', 2101))
except Exception:
print 'Connection failed'
sys.exit(1)
client.sendall(msg)
client.close()
您必须填写空白以获取您可能想要修改的任何其他内容。如果需要,可以删除try catch。
答案 1 :(得分:0)
当我在它之后放一个小的主循环时,你的原始代码对我(在MAC上)工作正常。
d = Device('127.0.0.1', 2101)
for n in range(5):
d.say_hi()
d.get_status()
d.say_bye()
然而,您的新设计更接近良好。不,不关闭连接根本不是一个好方法,但关闭它,然后立即重新创建它也不是一个好的设计。
如果只是添加一个close函数并在完成对象时调用它?
def close(self):
self.socket.close()
因此,例如我的代码将成为:
d = Device('127.0.0.1', 2101)
for n in range(5):
d.say_hi()
d.get_status()
d.say_bye()
d.close()
(也可以添加一个__del__
析构函数,它将在不再引用该对象后自动调用,但这通常是一个坏主意,因为在垃圾收集器运行之前它不一定会被调用,这可能是下个月。同时套接字描述符将保持打开状态。)