我不太确定为什么我的应用程序没有收到发送给它的消息。似乎正在发送消息。我看了这个例子作为参考。
how to listen to a specific port in qt using QTcpSocket?
我也尝试转换此c ++示例,但似乎未按预期发送任何消息:QTcpSocket: reading and writing
应该将接收到的消息打印到控制台,但是接收到的字节总是返回0。
import sys
from PyQt4 import QtNetwork, QtCore, QtGui
class Messenger(object):
def __init__(self):
super(Messenger, self).__init__()
self.TCP_HOST = '127.0.0.1' # QtNetwork.QHostAddress.LocalHost
self.TCP_SEND_TO_PORT = 7011
self.pSocket = None
self.listenServer = None
def slotSendMessage(self):
self.pSocket = QtNetwork.QTcpSocket();
self.pSocket.readyRead.connect(self.slotReadData)
self.pSocket.connectToHost(self.TCP_HOST, self.TCP_SEND_TO_PORT)
if not (self.pSocket.waitForConnected(1000)): # one second
print 'Unable to send data to port: "{}"'.format(self.TCP_SEND_TO_PORT)
return
cmd = "Hi there!"
print 'Command Sent:', cmd
ucmd = unicode(cmd, "utf-8")
self.pSocket.write(ucmd)
self.pSocket.waitForBytesWritten(1000)
# Do something with readData
self.pSocket.disconnectFromHost()
self.pSocket.waitForDisconnected(1000)
def slotReadData(self):
print 'Reading data:', self.pSocket.readAll()
# QByteArray data = pSocket->readAll();
class Client(QtCore.QObject):
def __init__(self, parent=None):
QtCore.QObject.__init__(self)
def SetSocket(self, Descriptor):
self.socket = QtNetwork.QTcpSocket(self)
self.connect(self.socket, QtCore.SIGNAL("connected()"), QtCore.SLOT(self.connected()))
self.connect(self.socket, QtCore.SIGNAL("disconnected()"), QtCore.SLOT(self.disconnected()))
self.connect(self.socket, QtCore.SIGNAL("readyRead()"), QtCore.SLOT(self.readyRead()))
self.socket.setSocketDescriptor(Descriptor)
print "Client Connected from IP %s" % self.socket.peerAddress().toString()
def connected(self):
print "Client Connected Event"
def disconnected(self):
print "Client Disconnected"
def readyRead(self):
msg = self.socket.readAll()
print type(msg), msg.count()
print "Client Message:", msg
class Server(QtCore.QObject):
def __init__(self, parent=None):
QtCore.QObject.__init__(self)
self.TCP_LISTEN_TO_PORT = 7011
def incomingConnection(self, handle):
print "Incoming Connection..."
self.client = Client(self)
self.client.SetSocket(handle)
def StartServer(self):
self.server = QtNetwork.QTcpServer()
self.server.incomingConnection = self.incomingConnection
if self.server.listen(QtNetwork.QHostAddress.Any, self.TCP_LISTEN_TO_PORT):
print "Server is listening on port: {}".format(self.TCP_LISTEN_TO_PORT)
else:
print "Server couldn't wake up"
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.setWindowTitle('TCP/Server')
self.resize(300, 300)
self.uiConnect =QtGui.QPushButton('Connect')
# layout
self.layout = QtGui.QVBoxLayout()
self.layout.addWidget(self.uiConnect)
self.widget = QtGui.QWidget()
self.widget.setLayout(self.layout)
self.setCentralWidget(self.widget)
# Connections
self.uiConnect.clicked.connect(self.setup)
def setup(self):
server = Server()
server.StartServer()
tcp = Messenger()
tcp.slotSendMessage()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
答案 0 :(得分:1)
您犯了以下错误:
您不应该使用waitForXXX方法,因为它们正在阻塞,从而阻止了事件循环的执行,因此未调用连接到信号的插槽。
不必执行self.server.incomingConnection = self.incomingConnection
,就像在不使用继承的情况下覆盖类那样,这样您就可以产生问题,而可以使用信号newConnection指示何时存在新连接,并使用nextPendingConnection( )以获取套接字。
考虑到上述情况,解决方案是:
import sys
from PyQt4 import QtCore, QtGui, QtNetwork
class Messenger(object):
def __init__(self):
super(Messenger, self).__init__()
self.TCP_HOST = "127.0.0.1" # QtNetwork.QHostAddress.LocalHost
self.TCP_SEND_TO_PORT = 7011
self.pSocket = None
self.listenServer = None
self.pSocket = QtNetwork.QTcpSocket()
self.pSocket.readyRead.connect(self.slotReadData)
self.pSocket.connected.connect(self.on_connected)
self.pSocket.error.connect(self.on_error)
def slotSendMessage(self):
self.pSocket.connectToHost(self.TCP_HOST, self.TCP_SEND_TO_PORT)
def on_error(self, error):
if error == QtNetwork.QAbstractSocket.ConnectionRefusedError:
print(
'Unable to send data to port: "{}"'.format(
self.TCP_SEND_TO_PORT
)
)
print("trying to reconnect")
QtCore.QTimer.singleShot(1000, self.slotSendMessage)
def on_connected(self):
cmd = "Hi there!"
print("Command Sent:", cmd)
ucmd = unicode(cmd, "utf-8")
self.pSocket.write(ucmd)
self.pSocket.flush()
self.pSocket.disconnectFromHost()
def slotReadData(self):
print("Reading data:", self.pSocket.readAll())
# QByteArray data = pSocket->readAll();
class Client(QtCore.QObject):
def SetSocket(self, socket):
self.socket = socket
self.socket.connected.connect(self.on_connected)
self.socket.disconnected.connect(self.on_connected)
self.socket.readyRead.connect(self.on_readyRead)
print(
"Client Connected from IP %s" % self.socket.peerAddress().toString()
)
def on_connected(self):
print("Client Connected Event")
def on_disconnected(self):
print("Client Disconnected")
def on_readyRead(self):
msg = self.socket.readAll()
print(type(msg), msg.count())
print("Client Message:", msg)
class Server(QtCore.QObject):
def __init__(self, parent=None):
QtCore.QObject.__init__(self)
self.TCP_LISTEN_TO_PORT = 7011
self.server = QtNetwork.QTcpServer()
self.server.newConnection.connect(self.on_newConnection)
def on_newConnection(self):
while self.server.hasPendingConnections():
print("Incoming Connection...")
self.client = Client(self)
self.client.SetSocket(self.server.nextPendingConnection())
def StartServer(self):
if self.server.listen(
QtNetwork.QHostAddress.Any, self.TCP_LISTEN_TO_PORT
):
print(
"Server is listening on port: {}".format(
self.TCP_LISTEN_TO_PORT
)
)
else:
print("Server couldn't wake up")
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.setWindowTitle("TCP/Server")
self.resize(300, 300)
self.uiConnect = QtGui.QPushButton("Connect")
# layout
self.layout = QtGui.QVBoxLayout()
self.layout.addWidget(self.uiConnect)
self.widget = QtGui.QWidget()
self.widget.setLayout(self.layout)
self.setCentralWidget(self.widget)
# Connections
self.uiConnect.clicked.connect(self.setup)
def setup(self):
self.server = Server()
self.server.StartServer()
self.tcp = Messenger()
self.tcp.slotSendMessage()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()