Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get IP address of sender when receiving message #50

Open
JellevanAbbema opened this issue Dec 28, 2019 · 4 comments
Open

Get IP address of sender when receiving message #50

JellevanAbbema opened this issue Dec 28, 2019 · 4 comments
Labels

Comments

@JellevanAbbema
Copy link

Hi,
For my application I need to be able to receive messages from all IP addresses which works fine by just using the OSCPortIn(port) constructor.
But I also need to send a reply to most received messages (on 1 port higher than I'm listening to). I want to do this by just sending an OSC message to that IP address but for that I need to know the IP Address from the sender (which can be anyone on the router). So I want to get the address when I receive a message but I don't know how to, or is there a better solution to this?

@hoijui
Copy link
Owner

hoijui commented Mar 28, 2020

I think, not even the Java basics (DatagramChannel in this case) would allow to do that.
I think you will have to create one OSCPortIn instance per address.

@JellevanAbbema
Copy link
Author

JellevanAbbema commented Mar 28, 2020

Well I've started to use a DatagramSocket and DatagramPacket, which does allow to get the senders IP address since all UDP packets contain their source. I'll probably end up just writing my own code for reading/writing OSC messages.

@hoijui hoijui added the feature label May 12, 2020
@Luftzig
Copy link

Luftzig commented Aug 3, 2020

I think, not even the Java basics (DatagramChannel in this case) would allow to do that.
I think you will have to create one OSCPortIn instance per address.

I have a similar problem, but since all my message sources send to the same server IP and port, only the latest one receives messages (on OSX). It is possible that it works correctly on newer Linux, in which processes can share a UDP port, but probably not on Windows (that I need to support).
If you know that creating a separate instance per connection works multiplatform, I'd be happy to see a working code example to compare to my own.

Luftzig pushed a commit to Luftzig/JavaOSC that referenced this issue Aug 3, 2020
Luftzig pushed a commit to Luftzig/JavaOSC that referenced this issue Aug 3, 2020
@JellevanAbbema
Copy link
Author

JellevanAbbema commented Aug 4, 2020

Alright, I'll just put my "solution" here since there are probably more people who could benefit from this.
Right now I'm not using any of the OSCPort classes, but I do use this library to (de)serialize the OSCMessages and the OSCMessage class itself.

And something else I would like to point out, since I parse the messages myself I could easily use this in a TCP ServerSocketChannel allowing OSC over TCP for more reliable communication and a future proof program, so right now I can listen to OSC messages on a UDP port as well as a TCP port (both can be on the same port btw).

As said before I'm using a DatagramSocket instead of a DatagramChannel in which we receive the whole packet that contains the sender IP as well as the port from which the packet is send (enough examples of this are available on the internet). But here is the code I use to parse the OSCMessage to a ByteBuffer and vice versa (this code is all copied from parts of the library). Parsing it to a ByteBuffer is for sending a response of course.

public static ByteBuffer parse(OSCMessage oscMessage){
    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
    OSCSerializerAndParserBuilder oscSerializerAndParserBuilder = new OSCSerializerAndParserBuilder();
    OSCSerializer serializer = oscSerializerAndParserBuilder.buildSerializer(buffer);
    buffer.rewind();
    try {
        serializer.write(oscMessage);
        buffer.flip();
    } catch (OSCSerializeException e) {
        e.printStackTrace();
    }
    return buffer;
}

public static OSCMessage parse(ByteBuffer buffer){
    OSCSerializerAndParserBuilder oscSerializerAndParserBuilder = new OSCSerializerAndParserBuilder();
    OSCParser parser = oscSerializerAndParserBuilder.buildParser();
    OSCPacket oscMessage = null;
    try {
        oscMessage = parser.convert(buffer);
    } catch (OSCParseException e) {
        e.printStackTrace();
    }
    return (OSCMessage) oscMessage;
}

I do need to point out that a DatagramPacket contains the data as a byte array, so you do have to wrap it to a ByteBuffer:
ByteBuffer.wrap(receivedPacket.getData())

I've also written my own code to handle messages after I receive them since I personally didn't like the way the library handles them (I also have a lot of different addresses and with the whole response thing I thought it would be a better solution).

@Luftzig using this there is no need to create separate instances for all Addresses (which I feel like is a shitty solution anyway).

I hope this gives a clear indication of what I did and is also good coding practice. (I'm still in a but of learning process when it comes to coding)

Luftzig pushed a commit to Luftzig/JavaOSC that referenced this issue Aug 18, 2020
Luftzig pushed a commit to Luftzig/JavaOSC that referenced this issue Aug 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants