2012-02-05 204 views
1

我有一个文件mc_send.py,它发送mcast消息,并且会从收到mcast消息mc_recv.py的程序接收一个单播消息。 mcast的工作,但收到单播消息时,返回一个奇怪的错误出现:ValueError: maximum length of data to be read cannot be negative错误是att行14在这个文件mc_send.py: 我已经在windows7与python2.7.2和pyqt4 v4.9这几个小时挣扎,但可以' t找到我做错了什么。这个程序基于pyqt4的广播例子。接收udp数据报时出现奇怪的错误

""" 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_()) 

回答

0

找到了症结,令人尴尬的简单的错误,写了self.udpSocket.pendingDatagramSize() 代替self.udpServer.pendingDatagramSize()当我正在读取数据时...