Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Best way to timeout connections with NIO.  (Read 5229 times)
0 Members and 1 Guest are viewing this topic.
Offline cep21

Junior Devvie




Java games rock!


« Posted 2006-08-01 06:11:23 »

I am using NIO and ServerSocketChannel.  After I create a connection, I can't wait more than 10 seconds between each input from the client.  Otherwise I want to timeout the connection.  This is while handling hundreds of connections at once.  What's the best way to do this?  What would be really cool is if my selector could return a key when a connection doesn't send me anything after 10 seconds.  I could also selector.select(1) and just test every 1 second but that seems like overkill.  Right now I have another Thread dealing with timeouts.  What's the best way to do this?

Thanks!
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 842
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2006-08-01 09:42:52 »

This should work.

mySocketChannel.socket().setSoTimeout(int timeout);


I don't know how a remote socket.setKeepAlive() changes the local behaviour though.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #2 - Posted 2006-08-01 09:58:49 »

This should work.

mySocketChannel.socket().setSoTimeout(int timeout);

I wouldn't use that, I dont think it does quite what you think it does (and it can be a bit odd on different platforms - but maybe that's not something OP is worried about, shrug)

Assuming OP can't just drop the connection "the next time it does something AFTER the ten seconds is up" (easiest way, normally most efficient too), I would:

 - each time you get a selectable key, set a timestamp in a map saying that you just received something at this time, with that key as the key
 - separate thread iterates over that map periodically finding victims, and uses the selectable key objects to remove them from the selector and drop the channel

malloc will be first against the wall when the revolution comes...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Kova

Senior Devvie





« Reply #3 - Posted 2006-08-01 12:45:26 »

that sounds like a good way to do it, but why in separate thread? You could check when last communication was done at the end of same (selector) thread, that is if you don't think it would slow every select noticably. I think it wouldn't.
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #4 - Posted 2006-08-01 14:59:33 »

that sounds like a good way to do it, but why in separate thread? You could check when last communication was done at the end of same (selector) thread, that is if you don't think it would slow every select noticably. I think it wouldn't.

Because I like my code efficient, i.e. I block on select, i.e. I would never get a chance to timeout the incoming connections Smiley. No other reason.

malloc will be first against the wall when the revolution comes...
Offline Kova

Senior Devvie





« Reply #5 - Posted 2006-08-01 15:08:22 »

right... I forgot about we're talking about blocking select, Riven mentioned select(1) and I got lost in it Smiley
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 842
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #6 - Posted 2006-08-01 15:30:32 »

right... I forgot about we're talking about blocking select, Riven mentioned select(1) and I got lost in it Smiley

Hoooo, I never said select(1) Kiss

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline Kova

Senior Devvie





« Reply #7 - Posted 2006-08-01 17:50:20 »

you MENTIONED it... no need to quote, look at your post
Offline cep21

Junior Devvie




Java games rock!


« Reply #8 - Posted 2006-08-01 19:09:36 »

mySocketChannel.socket().setSoTimeout(int timeout);

The javadoc says "With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time"  Because I'm using non blocking sockets and this function was written in 1.1, I'm not sure it will do what I want.  I don't want to just 'drop' the connection though.  I want to know when it was dropped so I can log it and clean up stuff.

Assuming OP can't just drop the connection "the next time it does something AFTER the ten seconds is up" (easiest way, normally most efficient too),

I'm afraid of some hax0r just making connections and letting them sit for an easy DoS.  On a non-hax0r note I want to notify the other plays that their opponent has timed out as soon as possible.

- each time you get a selectable key, set a timestamp in a map saying that you just received something at this time, with that key as the key
 - separate thread iterates over that map periodically finding victims, and uses the selectable key objects to remove them from the selector and drop the channel
I'm currently doing something very similar.  I have a DelayQueue running in another Thread.
Offline cep21

Junior Devvie




Java games rock!


« Reply #9 - Posted 2006-08-01 19:16:40 »

Because I like my code efficient, i.e. I block on select, i.e. I would never get a chance to timeout the incoming connections Smiley. No other reason.

If you block on select, how do you cleanly shutdown your application?  I wanted to make my design so that I could shutdown my server socket thread without having to System.exit(), so I have a shutdown boolean that I can set and loop like this:
1  
2  
3  
4  
while (!shutdownActivated){
    if (selector.select(500)!=0){
    }
}


I was thinking this lets me not spend to much in busy loop, while at the same time letting me cleanly shut down the thread without a system exit.  Do you know of a way to have my selector select a special key when I want to shutdown the application?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Kova

Senior Devvie





« Reply #10 - Posted 2006-08-01 22:31:33 »

use blocking selector, but when you need to exit the thread set the variable and call selector.wakeup() from another thread. See javadoc for details.
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 842
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #11 - Posted 2006-08-02 00:22:13 »

you MENTIONED it... no need to quote, look at your post

 Shocked


Let's quote myself then:

Quote
This should work.

mySocketChannel.socket().setSoTimeout(int timeout);


I don't know how a remote socket.setKeepAlive() changes the local behaviour though.

Where did I mention it???

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline Kova

Senior Devvie





« Reply #12 - Posted 2006-08-02 01:10:47 »

my appologies, cap21 mentioned it in his first pos, when scrooling breafly to see who posted I've looked wrong I guess. ... so much trash replys over nothing, moderator can erase those...
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #13 - Posted 2006-08-02 08:15:42 »

mySocketChannel.socket().setSoTimeout(int timeout);

The javadoc says "With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time"  Because I'm using non blocking sockets and this function was written in 1.1, I'm not sure it will do what I want.  I don't want to just 'drop' the connection though.  I want to know when it was dropped so I can log it and clean up stuff.

Assuming OP can't just drop the connection "the next time it does something AFTER the ten seconds is up" (easiest way, normally most efficient too),

I'm afraid of some hax0r just making connections and letting them sit for an easy DoS.  On a non-hax0r note I want to notify the other plays that their opponent has timed out as soon as possible.

Have you tried? Smiley

(you should be able to test that very easily with a second machien on your LAN!)

The overhead for additional open channels *using NIO* is sufficiently small that you shouldnt get significant problems beyond your OS problem of running out of sockets.

Even that probably isn't going to happen until long after your server crashes because of lack of open file handles Wink

And how hard is it for someone just to open the connections and then send junk every 1 second? Have you handled that fully?

(not trying to put you off doing it, just pointing out it's quite a long road to go down once you start worrying about that)

- each time you get a selectable key, set a timestamp in a map saying that you just received something at this time, with that key as the key
 - separate thread iterates over that map periodically finding victims, and uses the selectable key objects to remove them from the selector and drop the channel
I'm currently doing something very similar.  I have a DelayQueue running in another Thread.
Quote

malloc will be first against the wall when the revolution comes...
Offline cep21

Junior Devvie




Java games rock!


« Reply #14 - Posted 2006-08-02 17:43:55 »

To be clear, setSoTimeout does or does not work for NIO?  Everything in the doc says it is for blocking opperations.  Here is my test code that doesn't seem to do anything:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
while (true){
            if (selector.select()!=0){
                System.out.println("Selector returned.");
                Set keys=selector.selectedKeys();
                Iterator i=keys.iterator();
                while (i.hasNext()){
                    SelectionKey key=(SelectionKey) i.next();
                    i.remove();
                    if (key.isAcceptable()){
                        System.out.println("Got new one.");
                        ServerSocketChannel ss2=(ServerSocketChannel) key.channel();
                        SocketChannel newCon=ss2.accept();
                        newCon.configureBlocking(false);
                        newCon.register(key.selector(),SelectionKey.OP_READ);
                        newCon.socket().setSoTimeout(200); //***HERE IS MY TIMEOUT***
                    }
                    if (key.isReadable()){
                        ByteBuffer buf = ByteBuffer.allocateDirect(1024);
                        int numBytesRead = ((SocketChannel)key.channel()).read(buf);
                        if (numBytesRead==-1) {
                            key.channel().close();
                            continue;
                        }
                        buf.flip();
                        Charset myCharset = Charset.forName( "ISO-8859-1" );
                        System.out.println("Is readable:"+myCharset.decode(buf).toString());
                    }
                }
            }
        }
Offline Kova

Senior Devvie





« Reply #15 - Posted 2006-08-02 22:34:15 »

not related to problem itself, but why are you creating new bytebuffer every time? I just reuse the one I create before the loop.
Offline cep21

Junior Devvie




Java games rock!


« Reply #16 - Posted 2006-08-02 22:36:52 »

It's just test code to see if a feature works the way I think it should.  Not part of my application Smiley
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (37 views)
2014-12-15 09:26:44

Mr.CodeIt (30 views)
2014-12-14 19:50:38

BurntPizza (62 views)
2014-12-09 22:41:13

BurntPizza (99 views)
2014-12-08 04:46:31

JscottyBieshaar (59 views)
2014-12-05 12:39:02

SHC (74 views)
2014-12-03 16:27:13

CopyableCougar4 (77 views)
2014-11-29 21:32:03

toopeicgaming1999 (138 views)
2014-11-26 15:22:04

toopeicgaming1999 (127 views)
2014-11-26 15:20:36

toopeicgaming1999 (38 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!