收到udp数据报时出现奇怪的错误

时间:2012-02-05 18:48:32

标签: udp pyqt4

我有一个文件mc_send.py,它发送mcast消息,并从收到mcast消息的程序mc_recv.py收回单播消息。 mcast工作,但是当收到单播消息时,会出现一个奇怪的错误:ValueError: maximum length of data to be read cannot be negative错误在此文件mc_send.py中的第14行: 我在windows7上使用python2.7.2和pyqt4 v4.9这几个小时都在挣扎,但找不到我做错了什么。该程序基于pyqt4的广播示例。

""" to see all ports on windows: netstat -ap udp | find "4545" """
from PyQt4 import QtCore, QtGui, QtNetwork

unicast_addr = "127.0.0.1"
unicast_port = 45455
mcast_addr = "239.255.43.21"
mcast_port = 45454

class Sender(QtGui.QDialog):


    def processPendingDatagrams(self):
        while self.udpServer.hasPendingDatagrams():
            datagram, host, port = self.udpServer.readDatagram(self.udpSocket.pendingDatagramSize())
            print "got msg:", datagram

    def __init__(self, parent=None):
        super(Sender, self).__init__(parent)

        self.groupAddress = QtNetwork.QHostAddress(mcast_addr)
        self.unicastAddress = QtNetwork.QHostAddress(unicast_addr)

        self.statusLabel = QtGui.QLabel("Ready to multicast datagrams to group %s on port 45454" % 
                                        self.groupAddress.toString()) 

        # setup socket for listening on incomming datagrams
        self.udpServer = QtNetwork.QUdpSocket(self)
        self.udpServer.bind(unicast_port)
        self.udpServer.readyRead.connect(self.processPendingDatagrams)

        self.startButton = QtGui.QPushButton("&Start")
        self.quitButton = QtGui.QPushButton("&Quit")

        buttonBox = QtGui.QDialogButtonBox()
        buttonBox.addButton(self.startButton, QtGui.QDialogButtonBox.ActionRole)
        buttonBox.addButton(self.quitButton, QtGui.QDialogButtonBox.RejectRole)

        self.timer = QtCore.QTimer(self)
        self.udpSocket = QtNetwork.QUdpSocket(self)
        self.messageNo = 1

        self.startButton.clicked.connect(self.startSending)
        self.quitButton.clicked.connect(self.close)
        self.timer.timeout.connect(self.send_mc_msg)

        mainLayout = QtGui.QVBoxLayout()
        mainLayout.addWidget(self.statusLabel)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("WSim")

    def startSending(self):
        self.startButton.setEnabled(False)
        self.timer.start(1000)

    def send_mc_msg(self):
        self.udpSocket.writeDatagram("hello %d" %(self.messageNo), self.groupAddress, mcast_port)
        self.messageNo += 1

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    sender = Sender()
    sender.show()
    sys.exit(sender.exec_())

同样发送单播响应的多播接收器看起来像这样mc_recv.py:

from PyQt4 import QtGui, QtNetwork

mcast_addr = "239.255.43.21"
mcast_port = 45454
answer_addr = "127.0.0.1"
answer_port = 45455

class Receiver(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Receiver, self).__init__(parent)

        self.groupAddress = QtNetwork.QHostAddress(mcast_addr)        
        self.udpSocket = QtNetwork.QUdpSocket(self)
        self.udpSocket.bind(mcast_port, QtNetwork.QUdpSocket.ReuseAddressHint)
        self.udpSocket.joinMulticastGroup(self.groupAddress)
        self.udpSocket.readyRead.connect(self.processPendingDatagrams)

        # Use this socket to send unicast messages to back
        self.answerSocket = QtNetwork.QUdpSocket(self)
        self.answerAddress = QtNetwork.QHostAddress(answer_addr)        

        quitButton = QtGui.QPushButton("&Quit")
        quitButton.clicked.connect(self.close)

        buttonLayout = QtGui.QHBoxLayout()
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(quitButton)
        buttonLayout.addStretch(1)

        self.statusLabel = QtGui.QLabel("Listening for multicasted messages on %s" % mcast_addr) 
        mainLayout = QtGui.QVBoxLayout()
        mainLayout.addWidget(self.statusLabel)
        mainLayout.addLayout(buttonLayout)
        self.setLayout(mainLayout)

        self.setWindowTitle("mrecv")

    def processPendingDatagrams(self):
        """receive and decode multicast messages and send a response message on the return address"""

        while self.udpSocket.hasPendingDatagrams():
            datagram, host, port = self.udpSocket.readDatagram(self.udpSocket.pendingDatagramSize())
            self.statusLabel.setText("received mcast msg '%s'" % datagram)
            # send a response back to msend 
            self.answerSocket.writeDatagram("hi back", self.answerAddress, answer_port)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    receiver = Receiver()
    receiver.show()
    sys.exit(receiver.exec_())

1 个答案:

答案 0 :(得分:0)

发现原因,令人尴尬的简单错误,写过self.udpSocket.pendingDatagramSize() 当我读数据时,而不是self.udpServer.pendingDatagramSize()...