EsotericSoftware / kryonet

TCP/UDP client/server library for Java, based on Kryo
BSD 3-Clause "New" or "Revised" License
1.82k stars 419 forks source link

No UDP received from Server to Client on Android > 5.0 #106

Open codeflakes0 opened 9 years ago

codeflakes0 commented 9 years ago

I'm not sure the google group is still read so I'm reposting the issue here. Please see this post "https://groups.google.com/forum/#!topic/kryonet-users/7l436tftBlo" for details.

Basically with the simplest Client / Server application you can't send UDP from Server to Client on Android > 5.0. The same code works on Android 4.4.

UDP sending from Client to Server works though ...

PS: I've tested it on localhost so with Client and Server on the same device but this should not be a problem and the same code works on 4.4.

NathanSweet commented 9 years ago

It's still read, it's just I don't usually have time to setup and debug on Android, which tends to have buggy networking with OS version and device specific issues. Sorry I can't be of further help!

On Thu, Sep 3, 2015 at 11:28 PM, codeflakes0 notifications@github.com wrote:

I'm not sure the google group is still read so I'm reposting the issue here. Please see this post " https://groups.google.com/forum/#!topic/kryonet-users/7l436tftBlo" for details.

Basically with the simplest Client / Server application you can't send UDP from Server to Client on Android > 5.0. The same code works on Android 4.4.

UDP sending from Client to Server works though ...

PS: I've tested it on localhost so with Client and Server on the same device but this should not be a problem and the same code works on 4.4.

— Reply to this email directly or view it on GitHub https://github.com/EsotericSoftware/kryonet/issues/106.

codeflakes0 commented 9 years ago

Thank you for your answer Nathan. I've since checked as stated on the Google code forum that read() works and receive() returns null on android 5.0. I'm not familiar with the socket API and kryonet source code. Can I just use read() instead of receive() in readFromAdress() of UdpConnnection.java ?

codeflakes0 commented 9 years ago

The following patch seems to work on my test app.

public InetSocketAddress readFromAddress () throws IOException {
    DatagramChannel datagramChannel = this.datagramChannel;
    if (datagramChannel == null) throw new SocketException("Connection is closed.");
    lastCommunicationTime = System.currentTimeMillis();

    if(!datagramChannel.isConnected())
        return (InetSocketAddress)datagramChannel.receive(readBuffer); // always null on Android >= 5.0
    datagramChannel.read(readBuffer);
    return connectedAddress;
}
desertkun commented 9 years ago

codeflakes0, thank you SO MUCH! I've wasted 2 days trying to get this issue down, and finally.

CookedApps commented 8 years ago

How do i use this fix in gradle? I can't figure out how to download the latest commit by anubiann00b as jar repository.

desertkun commented 8 years ago

Just clone it and do mvn compile install to install it into your local maven repository. Also make sure to have mavenLocal() in your build.gradle script. Also, change compile to com.esotericsoftware:kryonet:2.22.0-RC1 in dependencies section.

CookedApps commented 8 years ago

I have installed maven and cloned the patched kronet version to my local maven repo and added mavenLocal() and compile "com.esotericsoftware:kryonet:2.22.0-RC1" to my build.gradle.. But udp is not working though, i think it takes kryonet from mavenCentral because the complie command for that is the same. But i need to use mavenCentral also for other repos.. So how do make the build.gradle to use the repo on my local maven? Thanks for your help desertkun!

desertkun commented 8 years ago

Just make sure to have mavenLocal before mavenCentral.

mavenLocal()
mavenCentral()
CookedApps commented 8 years ago

Yes, i have done it like that. So why isn't my Android 5 device receiving any udp messages? I have to make an addition here:

compile ("com.esotericsoftware:kryonet:2.22.0-RC1") {
         exclude module : 'kryo'
}
compile "com.esotericsoftware:kryo:3.0.1"

This is how my compile looks like. I had to exclude kryo from kryonet and complie it seperately because if i only compile java "com.esotericsoftware:kryonet:2.22.0-RC1" i get an Multiple dex file exception.

doomtoo commented 8 years ago

Thanks also codeflakes0! Saved a lot of headache, and working for me on my newer Android devices now. Just switched to using UDP and TCP, and of course doesn't work on any but the oldest Android, but I was lucky to find this post.

Now if only I could figure out how to get UDP to register not based on initial IP... (when connecting from an external IP, it first gets the first message from the router IP, than the internal IP, so kryo discards every message after that because they aren't from a registered IP) :/

russnes commented 7 years ago

Thanks a lot @codeflakes0 , and the team for making this great project! This makes it work, however after implementing this fix I have an issue with connections taking a long time to establish, and I get a lot of warnings that look like this:

Long monitor contention event with owner method=void com.esotericsoftware.kryonet.Client.connect(int, java.net.InetAddress, int, int) from Client.java:170 waiters=0 for 128ms

Long monitor contention event with owner method=int java.nio.SelectorImpl.selectInternal(long) from SelectorImpl.java:170 waiters=0 for 251ms

Long monitor contention event with owner method=int libcore.io.Posix.poll(android.system.StructPollfd[], int) from Posix.java:4294967294 waiters=0 for 248ms

The java.nio.SelectorImpl warning greatly outnumber the others.

Any chance anyone else has faced this issue and come up with a solution?

crykn commented 7 years ago

The project itself wasn't updated for more than two years – have you tried using one of the newer forks?

russnes commented 7 years ago

You're right. No, I haven't, and since everything works with this one and I'm running my project on many different platforms and setups I was hoping I could stick with what I got implemented. Would you be able to recommend one though?

crykn commented 7 years ago

There are three main forks:

russnes commented 5 years ago

FYI I've been testing on different platforms, and the issue seems to have been resolved starting from Android 7.0, API 24. The patch that I have seen implemented for this issue (the one proposed by @codeflakes0 here) for me at least caused the time spent connecting to increase tremendously, which made my app look like it wasn't working.

crykn commented 5 years ago

If anyone is looking for a code base without the fix, my fork allows you to disable it by setting UdpConnection#androidFixDisabled.