python套接字连接在Mac上被拒绝但在Windows

时间:2017-03-22 21:14:16

标签: python windows macos sockets

这不是connection refused的重复。此问题询问MacOSWindows之间的区别。此外,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)

2 个答案:

答案 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__析构函数,它将在不再引用该对象后自动调用,但这通常是一个坏主意,因为在垃圾收集器运行之前它不一定会被调用,这可能是下个月。同时套接字描述符将保持打开状态。)