read UDP string


photo

Recommended Posts

Hello,

 

We are using Unigine 1.0 for our project.

 

I am trying to get UDP data from Unigine, which is sent by an external program.

 

The external program is in python and it works well:

import socket
import sys
import time

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
while True:
    sock.sendto('ABCDE', ('192.168.1.204', 3002))
    time.sleep(0.1)

The following is the related part of my Unigine script. I have deleted the debug/control messages for brevity, which do not report an error.

class ListenerSocket {public:
    Socket socket;


    ListenerSocket(string ip, int port) {
        socket = new Socket(SOCKET_DGRAM,ip, port);
        socket.bind();
        socket.nonblock();
        thread("GetData", this);
    }


    ~ListenerSocket() {
        if ((socket != NULL) && (socket.isOpened())) {
            socket.close();
            delete socket;
        }
        socket = NULL;
    }
};


void GetData(ListenerSocket listener) {
    if(listener.socket.isOpened()) {
        Socket soc = listener.socket;
        while(1) {
            log.message(format("Received: \"%d\"", soc.readChar()));
            wait;
        }
    }
}


void create_scene() {
    ListenerSocket listener_socket1 = new ListenerSocket("192.168.1.204", 3002);
}

This script, when run, prints a bunch of zeroes (when python is not sending), and then prints a 65. It doesn't print the rest of the string.

I would like it to print "ABCDE", but I can't seem to do it because:

- I am unable to get more than one character from a udp stream at a time

- I am unable to figure out what kind of variable to store it in.

 

The example scripts don't say much about sending/receiving strings over udp, which is what I am trying to accomplish.

I will appreciate it very much if you can help me with some example code.

 

 

Link to post

Hi yigitakkok,

I think datagram sockets are not the right choice for what you are trying to accomplish.
When you send 'ABCDE' through the Python socket, it creates packet of 5 bytes.
readChar() for Unigine socket internally leads to recvfrom() call with parameter len = 1.
The behavior of datagram sockets is to discard excess bytes of a packet when it is larger then a buffer provided for recv() or recvfrom().
So this way you can read only the first character of a message.

Moreover, interface inherited from Stream class is just not suitable for datagram sockets, please avoid using it.
It was our design mistake to combine UDP and TCP sockets into one class.

Anyway, I see two ways:
1. Switch to TCP and use readString().
But keep in mind that readString() expects a null-terminated string preceded with string size (with trailing null character) in an integer value.
So to send string from Python you should do something like this:

import struct

message = 'ABCDE'
sock.send(struct.pack('<i', len(message) + 1))
sock.send(message + '\0')

2. If you want to communcate only messages of fixed size, use read() method on Unigine UDP socket.
But here is another problem: how to convert int vector to string?
I cannot come up with anything better than:

int buffer[0] = ();
if(socket.read(buffer,PACKET_LENGTH)) {
    string message = "";
    forloop(int i = 0; buffer.size()) message += format("%c",buffer[i]);
}
Link to post