不通过网络发送的消息(Python - 套接字)

时间:2015-09-06 10:48:54

标签: python sockets networking

我正在实施一个简单的聊天应用程序,您可以在客户端之间发送消息。如果客户端在同一网络上,它可以正常工作,但我想知道如果客户端不在同一网络上,如何使其工作。需要额外的步骤是什么?

我在下面提供了我的代码,适用于同一网络通信。 serve()在其自己的线程中运行并侦听传入的消息(通过调用rcvMsg())。当用户想要从mainprocess发送消息时,它会调用sendMsg()

class CMsgGateway(QtCore.QThread):

    def __init__(self, mainprocess, parent = None):  

        QtCore.QThread.__init__(self, parent)
        self.exiting = False
        self.mainprocess= mainprocess
        self.msgRcvd = ""
        serveThread = Thread(target=self.serve).start()

    def serve(self):

        while 1:
            self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
            self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.sock.bind(("", self.mainprocess.port))
            self.sock.listen(1)   
            self.rcvMsg()

    def rcvMsg(self):
        serverSocket, info = self.sock.accept()
        while 1:
            try:            
                buf = bytearray(4000)
                view = memoryview(buf)
                bytes = serverSocket.recv_into(view, 4000)
                if bytes:
                    stx = view[0]
                    Size = view[1:3]
                    bSize = Size.tobytes()
                    nTuple = struct.unpack(">H", bSize)
                    nSize = nTuple[0]
                    message = view[0:3+nSize]
                    messageString = message.tobytes().decode("utf-8").strip()
                    self.mainprocess.msgs += "Friend: " + messageString
                    self.emit(Qt.SIGNAL("msgRcvd"))
                else:
                    break
            except socket.timeout:
                print("Socket timeout.")
                sys.stdout.flush()
                break

    def messageReceived(self):

        self.mainprocess.slotMsgRcvd(self.msgRcvd)

    def sendMsg(self, msgToSend, IP):

        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 2)
        self.sock.connect((IP, self.mainprocess.port))
        self.sock.send(msgToSend.encode())
        self.sock.close()

尝试交叉网络时收到的错误是:

Traceback (most recent call last):
  File "chatApp.pyw", line 74, in slotMsgSend
  File "C:\Users\me\documents\chatApp\source\msginterface.pyw", line 61, in sendMsg
    self.sock.connect((IP, self.mainprocess.port))
OSError: [WinError 10051] A socket operation was attempted to an unreachable network

1 个答案:

答案 0 :(得分:0)

<强>更新

您已在问题中添加了回溯,表明远程网络无法访问。在这种情况下,您的代码充当客户端,因此我的原始答案并不直接解决您的问题,但是,一般原则是相同的,即无法联系远程主机,因为没有到达网络的路由主持人在听。

我认为您需要查看本地网络配置才能解决问题 - 您的代码不会出现问题。您可能需要设置到远程网络的路由...我不是Windows用户,但您可以查看route命令,可能this answer可能有帮助。

原始回答

是什么让您认为它在不同网络上的客户端之间不起作用?您是否能够测试来自不同网络的连接?

网络之间的路由消息通常不在应用程序层代码中完成,而是使用应用程序外部的网络设备(如路由器)的组合来执行。

因为您的代码将套接字绑定到主机名'',所以您的应用程序正在侦听运行它的主机上的所有可用接口。如果存在从客户端到服务器的路由,则与客户端连接所在的服务器没有区别。

你问&#34;有什么额外的步骤?&#34;。就你的代码而言,不应该是任何代码。但是,您可能需要在客户端和/或服务器上配置路由表,打开防火墙端口以允许来自/到客户端和服务器的双向流量,或配置路由器以引导网络之间的流量。有关如何做到这一点的详细信息超出了SO的范围。

相关问题