Java: Communicating data from one thread to another - java

I am working on creating a chat client based on UDP. The main structure is that there is a server where clients register and where clients can also request to form a connection with another client that is registered with the server. The clients are structures as follows using pseudo code:
public UDPClient() {
// Create datagram socket
// Execute RECEIVE thread using datagram socket above
// Execute SEND thread using datagram socket above
}
The idea is to have the send and receive executing on separate threads so I don't get blocked I/O on the receive. Both of these threads have loops within their run methods that allow you to continually send and receive messages. The problem I have is this. If a message comes in on the RECEIVE thread that changes how my SEND should be executing, how do I communicate this to the SEND thread? Do I have to shoot a datagram off to myself or can I communicate this in the code somehow?

Assuming boths threads have no reference to each other, create a third singleton class, which both read/send threads (classes) reference, that has a volatile member field to store the state data you want shared and which has synchronized access.
The volatile keyword, combined with synchronized access, guarantees that a change made to the field by one thread will be seen by another thread. Without this, changes may not be visible due to the java memory model specification.
Edited:
Following "separation of concerns" design guideline, it would be better to not have the read/send threads know about each other and to use a third class to orchestrate their activities/behaviour. Add methods to your read/send classes to stop(), start() etc and call these from the other class.
Using a separate class would also allow:
Behaviour control by other means, for example a "stop sending" button on an admin web page
Allowing multiple threads of each type, yet still having proper control through a central point, perhaps using a pool of such threads (without a separate class, you would have a many-to-many nightmare and lots of code that has nothing to do with the job at hand: ie ending and receiving)
Easier testing of your worker classes, because they do less and are more focused
porting/embedding them stand-alone for other uses

your SEND thread should have public (accesible) method (synchronized if possible) that you should be able to access from your RECEIVE thread. You could use this method to create a boolean flag, string message, etc. that you should always read before you .send(yourPacket); from your SEND thread.

Have a member variable in your READ method that your code can read from and change the SEND method based on that variable.

Related

Thread safety when using jNetPcap to send and receive Ethernet frames

I have a Java project where I am required to both send and receive network packets with only the Ethernet header present. The header contains custom MAC addresses as well, which do not match the physical hardware address of the receiving/sending interface.
I have selected jNetPcap 1.3 to accomplish this task, but I am concerned about the thread safety of my Java application and am in need of some help with the particularities of libpcap.
I have two threads, where the first thread executes a
org.jnetpcap.Pcap.loop(Pcap.LOOP_INFINITE, handler, outputQueue)
loop to capture packets from a previously opened org.jnetpcap.Pcap Object (representing a pcap_t) passed to the thread by the caller.
The second thread is supposed to pick payload/header pairs from an input queue and send them using
org.jnetpcap.Pcap.sendPacket(packetByteBuffer)
using the SAME org.jnetpcap.Pcap Object as the thread executing the reception loop.
Problem:
From using google I concluded that this approach is not working because libpcap is not threadsafe when accessing the same pcap_t object from different threads.
Theoretical Solution:
I think the solution to my problem is to create two separate instances of org.jnetpcap.Pcap, open them separately using org.jnetpcap.Pcap.openLive() and passing one instance to the transmission thread and one to the reception thread.
Before I run off changing a lot of code, I hope someone can confirm that this is indeed the right approach to solving this problem.
Thanks in advance for your answers.
You must in some way synchronize access between the threads, e.g. you could use
Pcap.breakloop() and break the loop that receives packages to send some and continue the loop afterwards.
Pcap.dispatch() and a short timeout for Pcap.openLive() and switch between queued packages to be send and receiving packages.
From the jNetPcap Documentation: It is however safe to interact with various Pcap objects from multiple threads, as long as access is externally synchronized.

Is it possible to use multiple java ObjetOutputStream objects to write to a single java ObjectInputStream object?

I have a standard client/server setup.
The program I'd like to build acts a lot like a mail office(which is my Server). Multiple people (client with ObjectOutputStream) hand the office (server with the single ObjectInputStream) mail with an attached address and the office sends the mail where it is supposed to go. If possible, I'd like to have one ObjectInputStream in the server that blocks, waiting for "mail" to come in from any ObjectOutputStream, then sends the "mail" where it's supposed to go. This way I can just have one thread that is completely dedicated to receiving data and sending it.
I will have a thread for each person's client with their ObjectOutputStream, but would like to not also need a matching thread in the server to communicate with each person. I am interested in this idea because I find it excessive to build tons of threads to separately handle connections, when it's possible that a single thread will only send data once in my case.
Is this feasible? or just silly?
Use a JMS queue of Java Message Service, is the design pattern for this case.
http://en.wikipedia.org/wiki/Java_Message_Service
If you have in the server app just one instance of ObjectInputStream and you have many clients then this instance needs to be shared by all threads thus you need to synchronize the access to it.
You can read more here. Hope this helps.
OR
You can have a pool of ObjectInputStream instances and using a assignment algorithm like Round Robin (doc) you can return the same instance for each x order thread for example ... this will make the flow in the server app to be more paralleled
Your question doesn't make sense. You need a separate pair of ObjectInputStream and ObjectOutputStream per Socket. You also need a Thread per Socket, unless you are prepared to put up with the manifest limitations of polling via InputStream.available(), which won't prevent your reads from blocking. If you are using Object Serialization you are already committed to blocking I/O and therefore to a thread per Socket.

TCP Client Accepting Objects

I am writing a java program that needs to continuously accept serialized objects throughout the run of the application. The objects are sent by a server as requested by the user.
My main application initializes the tcp client (extends thread) in its run method, but I am trying to read objects from the line from a function.
Pseudocode follows:
*tcp client extends thread
*global vars: ip, port, socket, oi stream, oo stream, object reference
*run()
make connection
*getObject()
object reference = (object).readobject()
return object
My main application calls client.getObject() in an update loop. there may or not be an object waiting.
Am I going about this the wrong way?
Are you trying to do "classic" server behavior or non-blocking IO?
If it's the former, I'd recommend a blocking queue on the server to accept incoming requests and a pool of threads to process them. Have the server assign a thread to process the request when it comes in until the thread pool is exhausted; queue up requests until threads are freed up and returned to the pool.
Non-blocking IO is another matter entirely. Look at how Netty and node.js are designed and implemented for that.
I would never have a class extend Thread - it's unlikely that you'll add significant new behavior. Implement Runnable instead and give it to a Thread instance to run.
I would suggest your run() method reads all the objects and adds them to a queue.
getOject() takes the next object from the queue.
You can also have a int queueLength() to check how any are waiting.

Java concurrency, access socket in parent thread

I'm developing a simple network client/server. The client has a MainConnection class which maintains the connection to the server and starts worker threads based on information coming in. I want the worker threads to send feedback on their progress to the server via the main connection. I’m not sure if I should have a public static synchronized method in MainConnection for sending data, or pass a Session object to the threads which would contain the Socket and a synchronized method for sending data.
It does not matter which design will you choose. It is really up to you. The only thing you should care about is to avoid 2 threads writing to the same stream concurrently. So, you can create your own layer that is synchoronized and used by several threads. Alternatively you can create synchronized output stream and pass it to all threads. This is probably the best approach: in this case each thread just knows to write stuff to the stream. The only layer that knows that stream is synchronized is a factory that creates it.

Polling servers at the same port - Threads and Java

I'm currently busy working on an IP ban tool for the early versions of Call of Duty 1. (Apparently such a feature wasn't implemented in these versions).
I've finished a single threaded application but it won't perform well enough for multiple servers, which is why I am trying to implement threading.
Right now, each server has its own thread. I have a Networking class, which has a method; "GetStatus" -- this method is synchronized. This method uses a DatagramSocket to communicate with the server. Since this method is static and synchronized, I shouldn't get in trouble and receive a whole bunch of "Address already in use" exceptions.
However, I have a second method named "SendMessage". This method is supposed to send a message to the server. How can I make sure "SendMessage" cannot be invoked when there's already a thread running in "GetStatus", and the other way around? If I make both synchronized, I will still get in trouble if Thread A is opening a socket on Port 99999 and invoking "SendMessage" while Thread B is opening a socket on the same port and invoking "GetStatus"? (Game servers are usually hosted on the same ports)
I guess what I am really after is a way to make an entire class synchronized, so that only one method can be invoked and run at a time by a single thread.
Hope that what I am trying to accomplish/avoid is made clear in this text.
Any help is greatly appreciated.
Right now, each server has its own thread.
Why do you need two servers in the same application?!? If you break both of the servers out into separate application, then you're still going to have the same issue if both of them try to use the same port... i.e. you have to dedicate a port for each server. If it's really a problem with the threading, then read below for ideas on how to fix this.
It's not possible for two threads to execute properly synchronized methods of the same class... if you have proper synchronization then there is no way to experience what you're describing. Here is what your class should look like:
class Networking
{
public synchronized Status getStatus() {
Status stat = new Status();
// ...
// Get status logic
// ...
return stat;// return the status
}
public synchronized void sendMessage(Message msg) {
// ...
// Send the message logic
// ...
}
}
So as long as you're invoking those methods on the same Networking instance (i.e. you don't have a separate instance of the Networking class for each thread), then you should not see any issues. Here is what the synchronized keyword does for you:
First, it is not possible for two invocations of synchronized methods on
the same object to interleave. When
one thread is executing a synchronized
method for an object, all other
threads that invoke synchronized
methods for the same object block
(suspend execution) until the first
thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a
happens-before relationship with any
subsequent invocation of a
synchronized method for the same
object. This guarantees that changes
to the state of the object are visible
to all threads. (ref)
If you want to have synchronization of the methods across all of the instances of the Networking class then you need to use synchronization statements:
class Networking
{
private static final Object lock = new Object();
public synchronized Status getStatus() {
synchronized(lock){
Status stat = new Status();
// ...
// Get status logic
// ...
return stat;// return the status
}
}
public synchronized void sendMessage(Message msg) {
synchronized(lock){
// ...
// Send the message logic
// ...
}
}
}
will [ I ] still get in trouble if Thread A
is opening a socket on Port 99999 and
invoking "SendMessage" while Thread B
is opening a socket on the same port
and invoking "GetStatus"?
There are two separate issues here. ( beyond the fact that 99999 is not a valid port # )
UDP by it's nature is meant for multiplexed one to many style communications. You can open a single socket and use that single socket to communicate with as many servers as you want. You don't have to worry about synchronization in the sense of one thread sending and another receiving on the same socket or two threads trying to send simultaneously because the read and write operations to the socket are atomic from the applications point of view. When you send on a UDP socket you are invoking a system call which copies N bytes of data from the application's memory space into a buffer in the OS kernel's memory space, and the kernel assembles that data into a UDP packet which is put on a queue for sending - all in a manner which looks atomic to the application. The same occurs when reading from a UDP socket except in reverse; distinct packets exist in a receive buffer in the kernel and when your application reads the socket the data in those packets is atomically copied from the kernel buffer into your application's buffer, one packet per read operation.
The second issue is managing incoming and outgoing data to specific servers. It sounds like you want to have one thread per server which maintains state / status regarding that server. When sending, you don't have to worry about synchronization at all. All the threads can send from the same socket and synchronization is effectively handled by the OS kernel.
However, receiving is a completely different issue. I would recommend having one thread whose only job is to read incoming packets off the socket and de-multiplex them. Each server thread would have a thread safe queue into which the reader thread would copy the incoming packets. Then each server thread doesn't have to worry about anything other than reading packets out of it's own incoming packets queue - it doesn't have to deal with reading from the socket at all.
I think you may be misunderstanding how sockets work and getting client and server ends of sockets confused. If you're sending a message, that usually done from a client socket. These are not bound to a static port number - it's the server socket (the one you call accept() on) that is bound to a specific port.
You can have as many clients as you need (up to some reasonable limit - there is a max of ca. 60,000 client connections) from any one network interface.
For an introduction to client and server-side sockets, see the Sun Lesson: All About Sockets

Categories