How do I signal a sleeping thread in Java? - java

I'm writing a UDP client-server pair for a networks class, and I have hit on a problem. This is a rather unorthodox networks assignment, so a little background first:
The goal is to create a server to implement push-based notifications. The key point here is that the server has to contact the client at whatever address it was last seen, as well listen for the client's control packets. So therefore, I have a thread running on the client periodically sending out UDP packets to the server, which logs their origin for when it needs to send out a response. This technique also busts through NAT's, as the send refreshes the address translation.
So then, here is my dilemma: Unless I'm mistaken, the NAT maps its own address and a generated port number onto it's clients address port combination. Therefore, in order to successfully traverse the NAT, I need to move all my packets through one port on the client machine. The updater thread would simply have to listen for a time, push out an update packet, and go back to listening.
Then here is where it get hairy. If the original thread, which wants to perform some action, wants the port, it has to wake the announcer, which is blocking while waiting for the response.
How can I pull this off in Java?
P.S.: If it turns out that the NAT would allow a communication on a different port to go through, then things are awesome.

Note: I am not necessarily telling you this is the right way to solve your larger problem.
But the answer to your top-line question, "How do I signal a sleeping thread in Java" is: Call interrupt() on the thread. You'll need a more elaborate mechanism in place to communicate why it has been interrupted, but that's a start. interrupt() will wake a sleep()ing or wait()ing thread with an InterruptedException, but I don't think that's really what you're asking.
This will not wake up a thread blocked on a read() call, say a socket. It sounds like you are using a DatagramSocket, in which case you have a couple of options:
Use a non-blocking implementation. (aka, "Selector-based", or New I/O (nio) in Java lingo) See e.g. DatagramChannel; also maybe this SO question and/or this one
Use normal Java I/O, set a socket timeout of suitable length, and wrap your calls to read() in a loop, checking for the appropriate condition.

Look at the following links :
Thread signaling
What is a condition variable in java
Java signal handling

How is the thread 'sleeping'?
Typically, inter-thread cooperation revolves around
wait() and notify() calls.

Selectors are one approach I would consider. Haven't used Java's version yet, so take this with a grain of salt.
You could have one selector watching both the UDP channel and an in-process channel, waking up on activity of either.
There's an introduction to selectors halfway down http://java.sun.com/developer/technicalArticles/releases/nio/ . See also the API docs of AbstractSelector and its interface.

Related

Java multicast listening and IGMP

I have an issue that is driving me crazy! Both design-wise and tech-wise.
I have a need to listen to a LOT of multicast addresses. They are divided into 3 groups per item that I am monitoring/collecting. I have gone down the road of having one process spin-up 100 threads. Each thread uses 2 ports, and three addresses/groups. (2 of the groups are on same port) I am using MulticastChannel for each port, and using SELECT to monitor for data. (I have used datagram but found NIO MulticastChannel much better).
Anyway, I am seeing issues where I can subscribe to about a thousand of these threads, and data hums along nicely. Problem is, after a while I will have some of them stop receiving data. I have confirmed with the system (CentOS) that I am still subscribed to these addresses, but data just stops. I have monitors in my threads that monitor data drops and out-of-order via the RTP headers. When I detect that a thread has stopped getting data, I do a DROP/JOIN, and data then resumes.
I am thinking that a router in my path is dropping my subscription.
I am at my wits end writing code to stabilize this process.
Has anyone ever sent IGMP joins out the network to keep the data flowing? Is this possible, or even reasonable.
BTW: The computer is a HP DL380 Gen-9 with a 10G fiber connection to a 6509 switch.
Any pointers on where to look would really help.
Please do not ask for any code examples.
The joinGroup() operation already sends out IGMP requests on the network. It shouldn't be necessary to send them out yourself, and it isn't possible in pure Java anyway.
You could economize on sockets and threads. A socket can join up to about 20 groups on most operating systems, and if you're using NIO and selectors there's no need for more than one thread anyway.
I have used datagram but found NIO MulticastChannel much better).
I don't know what this means. If you're referring to DatagramSocket, you can't use it for receiving multicasts, so the sentence is pointless. If you aren't, the sentence is meaningless.

Must a listening socket runs in thread?

I have some problems understanding how a socket should be handled. I get that server socket must runs in its own thread, because it must check if there are new connections. Now, i'm not sure if every socket opened by a new connection should runs in a thread.
What i have in mind is checking every x time the socket states. If it has something to be read, then read. If not, check the next socket. I see some examples where this process is done in a thread, but i dont want a socket to do stuff, just want to read if it has some data, and process them.
The answer is no, you don't need to listen in a separate thread. But, just realize that while you are "listening" your entire program will be waiting for that to complete before moving onward.
So unless you are fine with your entire program waiting, I would suggest a separate thread.
You can also have one thread which communicates with all sockets in a round-robin manner. It checks each socket if it has new data, and when it hasn't it checks the next.
Another alternative is to use NIO (New Input/Output).
The idea behind NIO is that you have a thread with one Selector which owns multiple Channels (a channel can be a network socket or any other IO interface). You then call selector.select() in a loop. This method blocks until one or more channels have data, and then returns a set of these channels. You can then process the data the channels delivered.
Here is a tutorial.
The problems with round-robin using available() are many.
It assumes that available() actually works, which isn't guaranteed.
It assumes that all clients need the same amount of service.
N-1 clients wait while one client is serviced.
A non-responsive client can block not only your application but all the other clients.
I'm sure there are more.
Don't do this. Use threads or NIO.

Handling multiple requests on a TCP/IP Socket

Is it quite easy to handle multiple requests on a Java TCP / IP socket. Simply accept a message and spawn a thread. Accept another message and spawn another thread. The thing is once you start spawning threads things get more non deterministic. Say you have 10 clients and one client keeps firing requests and the other 9 nine who send requests at 10% percent of the hyperactive client, find it harder to get a look in.
One way you could handle this is have a hashmap of semaphores in your server where every client has a corresponding semaphore. Before you handle a request for any client, you could make it go thru its semaphore and configure the semaphores so that each client could only have a certain number of requests at any one time.
At this stage,I'm thinking yeah that works but is there a better way or a library that does this?
... but is there a better way ...?
I use one accepting-thread per serversocket and a pool of pre-spawned threads to handle the workload. The accepting-thread only accepts connections (does nothing else) and gives the handler-socket to one of the threads in the pool. That thread then works with the handler-socket until the client is done, then closes the handler-socket.
You can scale-out this setup as far as you like: If you notice that the accepting-thread is waiting for pool-threads most of the time then you need to x2 your number of pool-threads, if you notice that the accepting-thread is the bottle-neck you create both (A) another accepting-thread and (B) another socket from which it accepts connections and optionally (C) put these on another machine.
The specific problem you are describing with the one hyper-active client can be intended/desired if the client is more important than others: in which case you have to do nothing. Or it can be considered a denial-of-service attack, in which case you should have a heuristic that just disconnects the client and temporarily bans its ip-address.

How to write an UDP server that will service n concurrent requests from different clients?

I am connecting 10 devices to a LAN, all of them have a udp server that goes like:
while(true){
serverSocket.receive(receivePacket);
dostuff(receivePacket);
}
serverSocket.close();
Now lets assume 9 of the devices try to initiate connection to the 10th device simultaenously. How can I accept all 9 instead of just the first which will then block the socket untill the server completes computation? Should I start a thread which will take care of dostuf() ? Will this let me get request from all of the simultaneous requests I got?
A basic design would have on thread responsible for handling incoming requests (with your desired limit) and then handing them off to worker/request handler threads. When each of these worker threads is finished, you'd want to update a shared/global counter to let the main thread know that it can establish a new connection. This will require a degree of synchronization, but it can be pretty fun.
Here's the idea:
serverThread:
while true:
serverLock.acquire()
if numberOfRequests < MAX_REQUESTS:
packet = socket.receive()
numberOfRequests++
requestThread(packet).run()
else
serverMonitor.wait(serverLock);
serverLock.release()
requestThread:
//handle packet
serverLock.acquire()
if numberOfRequests == MAX_REQUESTS:
numberOfRequests--
serverMonitor.pulse();
serverLock.release()
You'll want to make sure the synchronization is all correct, this is just to give you an idea of what you can start out with. But when you get the hang of it, you'll be able to make optimizations and enhancements. One particular enhancement, which also lends itself to limited number of requests, is something called a ThreadPool.
Regardless the basic structure is very much the same with most servers: a main thread responsible for handing off requests to worker threads. It's a neat and simple abstraction.
You can use threads in order to solve that problem. Since java already has an API that handles threads you can just create instance of runnable executors, take a look at the Executor Interface. Here is another useful link that could potentially help: blocking queue
Use a relatively larger size threadpool since udp doesn't require response.
main method will run as a listener and a threadpool will be doing rest of the heavy lifting

Socket communication of server with two different applications, Java

I am writing the code for a server that would help two different applications in different platforms communicate with each other. To visualize it a bit it would be something like this :
App1<------>Server<------>App2
What server does is rear var1 from app2, write it to app1, then read var2 from app1 and write it to app2. Like this :
while(true){
var1 = app2stream.readInt();
app1stream.writeInt(var1);
var2 = app1stream.readDouble();
app2stream.writeDouble(var2);
}
My problem is that at some point i have this code at my server :
app1.accept();
app2.accept();
What this means is that no matter what, and given the fact that the server is always running, app1 is the one that should connect first since app1.accept() is a blocking method.
Is there any way around this? It would be great to allow the two applications to connect to the server regardless of who "came" first and then wait for the server to proceed with the above code. Can i use threads just for the accept() part and then pass the streams to the other thread? I read a bit about channels but got a bit buffled, any examples would be great.
Use NIO
It allows you to do non-blocking sockets (including accept) using the Selector class.
Basically, it gives you much more native access to the system libraries and the ability to handle your task without having to multi-thread.
Only have one accept call, and one server socket. You can make the determination which app has connected once they connect. If you can't get it from the connection details, have them send an authcode (probably a good idea anyway) which you can map to your app.
You should probably treat them both the same unless they say otherwise.
For example when the each socket connects send a "what client?" message.
Then check whether the client responds with 1 or 2.
If both respond with 1 or something just disconnect both.
I think the "standard" way to do this is to have the server listening on a port, and when a message comes in, immediately spin off a new thread to handle it, then go back to listening for another message. Then, as Glowcoder says, make all the connections in the same loop and make it figure out which is which after connecting.
I suppose the alternative is to have multiple threads, each listening on different ports. I've never tried to do that, I'm not sure if one would block until a connection was made and so you'd never get to the other thread.

Categories