UDP

Client code:

from pandac.PandaModules import loadPrcFileData
loadPrcFileData("", "window-type none")
loadPrcFileData("", "client-sleep 0.001")

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.gui.DirectGui import *
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import * 
from pandac.PandaModules import * 
from pandac.PandaModules import Camera
from direct.task import Task 
import sys
class PandaUDPClient(DirectObject):
    def __init__(self):
        print "Hello my dog-faced opponents!" #Please excuse this... :p
        self.target = NetAddress()
        self.target.setHost('192.168.254.12',35167)
        self.initNetwork()

    def initNetwork(self):
        self.cManager = ConnectionManager()  
        self.cWriter = ConnectionWriter(self.cManager,0)
        self.connect()
    
    def connect(self):
        self.Connection = self.cManager.openUDPConnection()
        taskMgr.add(self.sendBlast, "sendBlastTask", -39)
    
    def readTask(self,task):
        pass

    def sendBlast(self,task):
        package = NetDatagram()
        package.addString("blast")
        self.cWriter.send(package,self.Connection,self.target)
        #taskMgr.doMethodLater(2,self.sendBlast,"sendBlastTask")
        return Task.done
    
Conn = PandaUDPClient()
run()

Server code:

from pandac.PandaModules import loadPrcFileData
loadPrcFileData("", "window-type none")
loadPrcFileData("", "client-sleep 0.001")

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import * 
from direct.task import Task 
from direct.distributed.PyDatagram import PyDatagram 
from direct.distributed.PyDatagramIterator import PyDatagramIterator 
import sys
class PandaUDPTest(DirectObject):
    def __init__(self):
        print "PandaUDP Test now starting..."
        self.initNetwork()
    
    def initNetwork(self):
        #self.cManager = ConnectionManager()  
        self.cManager = QueuedConnectionManager()  
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        #self.cReader = RecentConnectionReader(self.cManager)
        self.cReader.setRawMode(1)
        
        self.cWriter = ConnectionWriter(self.cManager,0)
        self.startServer()
        
    def startServer(self):
        self.udpSocket = self.cManager.openUDPConnection(35167)
        if not self.udpSocket:
            print "WARNING: cannot Create UDP socket connection"
        self.cListener.addConnection(self.udpSocket)
        print 'Number of threads: ', self.cListener.getNumThreads()
        taskMgr.add(self.listenTask,"serverListenTask",-40)
        taskMgr.add(self.readTask,"serverReadTask",-39)
        print "Server started"

    
    def listenTask(self,task):
        if self.cListener.newConnectionAvailable():
            print "New Connection Detected"
        return Task.cont 
    
    def readTask(self,task):
        if self.cReader.dataAvailable():
             print "New data available"
        return Task.cont



Test = PandaUDPTest()
run()

When I run the server code, its fine. But when the client code attempts to send one “Blast” message, the server gets this error:

:net(error): Error when accepting new connection.

And it just loops forever printing that.
Can anyone please help?
(This was based on my other code that uses TCP instead)

As long as it’s not read, there is data available…

    def readTask(self,task):
        if self.cReader.dataAvailable():
             print "New data available"
             # read the data...
        return Task.cont

hmm… this code outputs the same error, though…

    def readTask(self,task):
        if self.cReader.dataAvailable():
            print "New data available"
            datagram = NetDatagram()
            sender = datagram.getConnection()
            if self.cReader.getData(datagram):
                message = PyDatagramIterator(datagram)
                data = message.getString()
                print data
        return Task.cont

Please correct me!

:Edit:

Treeform pointed out to me yesterday that the error came from this:

void ConnectionListener::
process_incoming_data(SocketInfo *sinfo) {
  Socket_TCP_Listen *socket;
  DCAST_INTO_V(socket, sinfo->get_socket());

  Socket_Address addr;
  Socket_TCP *session = new Socket_TCP;
  if (!socket->GetIncomingConnection(*session, addr)) {
    net_cat.error()
      << "Error when accepting new connection.\n";
    delete session;

  } else {
    NetAddress net_addr(addr);
    net_cat.info()
      << "Received TCP connection from client " << net_addr.get_ip_string()
      << " on port " << sinfo->_connection->get_address().get_port()
      << "\n";

    PT(Connection) new_connection = new Connection(_manager, session);
    if (_manager != (ConnectionManager *)NULL) {
      _manager->new_connection(new_connection);
    }
    connection_opened(sinfo->_connection, net_addr, new_connection);
  }

  finish_socket(sinfo);
}

As I see it, whenever newConnectionAvailable is called, processIncomingData is also called. However, ConnectionListeners are for TCP connections, not for UDP. Thus, when I call self.cListener.newConnectionAvailable(),

:net(error): Error when accepting new connection.

shows up because it expected a TCP message, not a UDP, as I have sent it…

Now, Im wondering how to properly receive a UDP message…

UDP is received with a ConnectionReader, not a ConnectionListener. Since UDP is connectionless, there’s no need for TCP’s rendez-vous mechanism to establish a connection, and thus no need for a listener. Just create a ConnectionReader and start reading.

David

Also, I have made a simple copy when I was asking my UDP questions, just look up my user name.