Currently I am working on Java client/server chat app and got one question, I'll try to explain as clear as possible.
My server part keeps creating threads (new ServerThread) for each user who comes online:
while (isRunning) {
Socket socket = serverSocket.accept();
DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
outputStreams.put(socket, dout);
System.out.println (outputStreams.values());
new ServerThread(this, socket);
window.newConnectionInfo(socket);// informace
}
I have a getter method in a ServerThread class, which I want to call from the certain ServerThread instance based on socket. But ServerThread class isn't assigned to any variable, so I don't know exactly how to call methods from it. Any solution on that?
Easy, you need to locate and find the thread you want to force call a method, that you would keeps every thread you create, I suggest you the Map you are using for keeping clients would be in < ServerThread ,DataOutputStream >, so here you have all threads now (and Scoket instance inside the ServerThread), okay and the answer.
okay first you need a method for signalling the target thread in the ServerThread, like this
class ServerThread{
public void forceToCall(Object o){//an object argument, would be void too, or an interface
//do something, call someone
}
}
then, so who is going to call this method? simply create a class that would call the target client sync or async mode, just like this
class ClientMethodCaller implements Runnable{
ServerThread st;Object arg
public ClientMethodCaller(ServerThread st,Object arg){this.st=st;this.arg=arg;}
public void run () {
st.forceToCall(arg);//signalling the client async
}
}
and at the end, whenever you want to a client to run a specific method, just after finding the client(ServerThread) instance, call the target method by ClientMethodCaller
ServerThread st;//got the instance
new Thread(new ClientMethodCaller(st,"Hello!")).start();
and the final word, this is not good, running a thread for any client logins, IF the program, is not small and the number of users are to much.
also check this tutorial too, would help
Related
I've two clients on two different machines and I don't know when they're gonna send requests.
is this the scenario where I HAVE TO use Selector and ServerSocketChannel?
Example:
public class Server{
public static void main(String[] args) {
try(
ServerSocket serverSocket = new ServerSocket(1234)
){
while(true) {
serverSocket.accept();
Thread.sleep(5*1000);
//and while its sleeping, second client sends request
}
}catch(Exception e){}
}
}
is this the scenario where I HAVE TO use Selector and ServerSocketChannel?
Nope. A more common solution is to have one thread per client - when you accept a call, create a new thread (or use an existing one from a thread-pool) and use that to handle that connection. The original thread calls accept again (immediately - no sleep required) and spawns a new thread for the next connection, etc.
(There are certainly advantages to asynchronous IO, but you're not forced to use it.)
You dont have to use Selector / ServerSocketChannel.
Instead for a very simple server - you could simply start a new thread to handle the client connection. See Supporting Multiple Clients for an example on how to do this with a new thread per client.
I have a jar file that displays a JFrame when it is executed.
I don't want to allow duplicate execution of my Jar file.
Every time before creating the frame, using Java I want check whether the Jar is already executing. If my app. already has an instance on-screen, I want to bring it to front.
How can I do that?
Please suggest me a way.
There is no regular method in java for single instance of an application.
However you can use Socket programming technique to achieve your goal.
When the instance is creating it attempts to listen a ServerSocket. If it could open the ServerSocket it means there are no another instance of the application. So, it keeps the ServerSocket live until the program is shutdown. If it could not open the ServerSocket, it means the application already have another instance. So you can exit application silently. Additionally you don't need to reset your settings when shutdown the application.
Try following example
public class SingletonApplication extends JFrame implements Runnable {
//count of tried instances
private int triedInstances = 0;
//the port number using
private static final int PORT = 5555;
public static void main(String[] args) {
SingletonApplication application = new SingletonApplication();
application.setTitle("My Singleton Application");
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.setSize(500, 500);
application.setVisible(true);
}
public SingletonApplication() {
super();
//run socket listening inside a thread
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
try {
//create server socket
ServerSocket serverSocket = new ServerSocket(PORT);
//listing the socket to check new instances
while (true) {
try {
//another instance accessed the socket
serverSocket.accept();
//bring this to front
toFront();
//change the title (addtional);
triedInstances++;
setTitle("Tried another instances : " + triedInstances);
} catch (IOException ex) {
//cannot accept socket
}
}
} catch (IOException ex) {
//fail if there is an instance already exists
try {
//connect to the main instance server socket
new Socket(InetAddress.getLocalHost(), PORT);
} catch (IOException ex1) {
//do nothing
} finally {
//exit the system leavng the first instance
System.exit(0);
}
}
}
}
EDIT:
Additionally: It can pass your runtime arguments into the main instance of the application via the client Socket. So, it's possible to make the main instance to perform required task such opening file or playing music by adding some additional code to read the InputStream of accepted Socket when calling accept() method.
I had the same situation.
What I did is I used to open a file in write mode and delete the file when I close the application.
By doing this I have a known proof that my program is running.
Each time I open the application I check for the existence of that file and if I find my file, it is running then I used to alert him
"An instance is already running".
Even if one tries to delete that file it says that it is open in another application.
I used a socket too, via RMI.
The application is an RMI host/server, accepts a Remote Method Invokation on a port.
In the main, at startup on tries as RMI client to get an RMI server on that port.
Is it there one does a remote call passing the command line args (to open another document for instance). And then quits.
As a server on being called that remote method one brings the application to front using toFront() of the window.
JUnique accomplishes the first part--blocking multiple instances of the same program. Getting the existing instance to come to the front is another task that I'm not sure how to approach.
I'm writing an end-to-end test that my Java program releases all of its resources - threads, server sockets, client sockets. It's a library, so releasing resources by exiting the JVM is not an option. Testing the releasing of threads was easy, because you can ask a ThreadGroup for all threads in it, but I haven't yet found a good way to get a list of all network sockets that the current JVM is using.
Is there some way to get from a JVM the list of all client and server sockets, similar to netstat? I'm using Netty with OIO (i.e. java.net.ServerSocket and java.net.Socket) on Java 7. The solution needs to work on both Windows and Linux.
My first preference would be to ask it from the JVM using pure Java. I tried to look for an MX Bean or similar, but did not find any.
Another option might be to connect to the JVM's profiling/debugging APIs and ask for all instances of Socket and ServerSocket, but I don't know how to do that and whether it can be done without native code (AFAIK, JVMTI is native-only). Also, it shouldn't make the tests slow (even my slowest end-to-end test is just 0.5 seconds, which includes starting another JVM process).
If interrogating the JVM doesn't work, a third option would be to create a design which tracks all sockets as they are created. This has the disadvantage of having a possibility of missing some place where sockets are created. Since I'm using Netty, it seems implementable by wrapping ChannelFactory and using a ChannelGroup.
I was able to hook into java.net.Socket and java.net.ServerSocket and spy all new instances of those classes. The complete code can be seen in the source repository. Here is an overview of the approach:
When a Socket or ServerSocket is instantiated, the first thing in its constructor is a call to setImpl() which instantiates the object which really implements the socket functionality. The default implementation is an instance of java.net.SocksSocketImpl, but it's possible to override that by setting a custom java.net.SocketImplFactory through java.net.Socket#setSocketImplFactory and java.net.ServerSocket#setSocketFactory.
This is complicated a bit by all implementations of java.net.SocketImpl being package-private, but with a little bit of reflection that's not too hard:
private static SocketImpl newSocketImpl() {
try {
Class<?> defaultSocketImpl = Class.forName("java.net.SocksSocketImpl");
Constructor<?> constructor = defaultSocketImpl.getDeclaredConstructor();
constructor.setAccessible(true);
return (SocketImpl) constructor.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
The SocketImplFactory implementation for spying on all sockets as they are created looks something like this:
final List<SocketImpl> allSockets = Collections.synchronizedList(new ArrayList<SocketImpl>());
ServerSocket.setSocketFactory(new SocketImplFactory() {
public SocketImpl createSocketImpl() {
SocketImpl socket = newSocketImpl();
allSockets.add(socket);
return socket;
}
});
Note that setSocketFactory/setSocketImplFactory can be called only once, so you either need to have only one test which does that (like I have it), or you must create a static singleton (yuck!) for holding that spy.
Then the question is that that how to find out whether the socket is closed? Both Socket and ServerSocket have a method isClosed(), but that uses a boolean internal to those classes for keeping track of whether it was closed - the SocketImpl instance does not have an easy way of checking whether it was closed. (BTW, both Socket and ServerSocket are backed by a SocketImpl - there is no "ServerSocketImpl".)
Thankfully the SocketImpl has a reference to the Socket or ServerSocket which it is backing. The aforementioned setImpl() method calls impl.setSocket(this) or impl.setServerSocket(this), and it's possible to get that reference back by calling java.net.SocketImpl#getSocket or java.net.SocketImpl#getServerSocket.
Once again those methods are package-private, so a little bit of reflection is needed:
private static Socket getSocket(SocketImpl impl) {
try {
Method getSocket = SocketImpl.class.getDeclaredMethod("getSocket");
getSocket.setAccessible(true);
return (Socket) getSocket.invoke(impl);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static ServerSocket getServerSocket(SocketImpl impl) {
try {
Method getServerSocket = SocketImpl.class.getDeclaredMethod("getServerSocket");
getServerSocket.setAccessible(true);
return (ServerSocket) getServerSocket.invoke(impl);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Note that getSocket/getServerSocket may not be called inside the SocketImplFactory, because Socket/ServerSocket sets them only after the SocketImpl is returned from there.
Now there is all the infrastructure necessary for checking in our tests whatever we want about the Socket/ServerSocket:
for (SocketImpl impl : allSockets) {
assertIsClosed(getSocket(impl));
}
The full source code is here.
I haven't tried it myself, but the JavaSpecialists newsletter presents a similar problem:
http://www.javaspecialists.eu/archive/Issue169.html
At the bottom, he describes an approach using AspectJ. You could probably put the pointcut around the constructor that creates the socket, and have code that registers socket creation there.
I saw plenty of similar questions on SO but hardly any of them have Socket in the picture. So please take time to read the question.
I have server app (using ServerSocket) which listens for requests, and when a client attempts to connect, new thread is created to serve the client (and server is back to listening mode for new requests). Now, I need to respond one client based on what other client sent to server.
Example:
ServerSocket listening for incoming connections.
Client A connects, new thread is created to serve A.
Client B connects, new thread is created to serve B.
A sends message "Hello from A" to the Server.
Send this message as a response to Client B.
I'm new to this whole "inter-thread communication" thing. Obviously, above mentioned situation sounds dead simple, but I'm describing this to get a hint, as I'll be exchanging huge amount data among clients keeping server as intermediate.
Also, what if I want to keep a shared object limited to, say 10, particular Clients? such that, when 11th client connects to the server, I create new shared object, which will be used to exchange data between 11th, 12th, 13th..... upto 20th client. And so on for every single set of 10 clients.
What I tried: (foolish I guess)
I have a public class with that object supposed to be shared as public static, so that I can use it as global without instantiating it, like MyGlobalClass.SharedMsg.
That doesn't work, I was unable to send data received in one thread to the other.
I'm aware that there is an obvious locking problem since if one thread is writing to an object, other can't be accessing it until the first thread is done writing.
So what would be an ideal approach to this problem?
Update
Since the way in which I create threads for serving incoming connection requests, I can't understand how I can share same object among the threads, since using Global object as mentioned above doesn't work.
Following is how I listen for incoming connections and create serving threads dynamically.
// Method of server class
public void startServer()
{
if (!isRunning)
{
try
{
isRunning = true;
while (isRunning)
{
try
{
new ClientHandler(mysocketserver.accept()).start();
}
catch (SocketTimeoutException ex)
{
//nothing to perform here, go back again to listening.
}
catch (SocketException ex)
{
//Not to handle, since I'll stop the server using SocketServer's close() method, and its going to throw SocketException anyway.
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
else
System.out.println("Server Already Started!");
}
And the ClientHandler class.
public class ClientHandler extends Thread
{
private Socket client = null;
private ObjectInputStream in = null;
private ObjectOutputStream out = null;
public ClientHandler(Socket client)
{
super("ClientHandler");
this.client = client;
}
//This run() is common for every Client that connects, and that's where the problem is.
public void run()
{
try
{
in = new ObjectInputStream(client.getInputStream());
out = new ObjectOutputStream(client.getOutputStream());
//Message received from this thread.
String msg = in.readObject().toString();
System.out.println("Client # "+ client.getInetAddress().getHostAddress() +" Says : "+msg);
//Response to this client.
out.writeObject("Message Received");
out.close();
in.close();
client.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
I believe that the way I'm creating dynamic threads to serve each client that connects, sharing the same data source is not possible using Global object, since the body of run() above is exactly the same for every client that connects, hence this same method is both consumer and producer. What fixes should I make such that I could create dynamic threads for each connection and still share the same object.
You probably want a queue for communication between each client. Each Queue will be the 'pipeline' for data pushed from one client to the other.
You would use it like so (pseudo code):
Thread 1:
Receive request from Client A, with message for Client B
Put message on back of concurrent Queue A2B
Respond to Client A.
Thread 2:
Receive request from Client B.
Pop message from front of Queue A2B
Respond to Client B with message.
You might also want it generic, so you have a AllToB Queue that many clients (and thus many threads) can write to.
Classes of note: ConcurrentLinkedQueue, ArrayBlockingQueue.
If you want to limit the number of messages, then ArrayBlockingQueue with its capacity constructor allows you to do this. If you don't need the blocking functionality, you can use the methods offer and poll rather than put and take.
I wouldn't worry about sharing the queues, it makes the problem significantly more complicated. Only do this if you know there is a memory usage problem you need to address.
EDIT: Based on your update:
If you need to share a single instance between all dynamically created instances you can either:
Make a static instance.
Pass it into the constructor.
Example of 1:
public class ClientHandler extends Thread
{
public static final Map<ClientHandler, BlockingQueue<String>> messageQueues
= new ConcurrentHashMap<>();
<snip>
public ClientHandler(Socket client)
{
super("ClientHandler");
this.client = client;
// Note: Bad practice to reference 'this' in a constructor.
// This can throw an error based on what the put method does.
// As such, if you are to do this, put it at the end of the method.
messageQueues.put(this, new ArrayBlockingQueue<>());
}
// You can now access this in the run() method like so:
// Get messages for the current client.
// messageQueues.get(this).poll();
// Send messages to the thread for another client.
// messageQueues.get(someClient).offer(message);
A couple of notes:
The messageQueues object should really contain some sort of identifier for the client rather than an object reference that is short lived.
A more testable design would pass the messageQueues object into the constructor to allow mocking.
I would probably recommend using a wrapper class for the map, so you can just call offer with 2 parameters rather than having to worry about the map semantics.
In Java, how would you set up a socket listener that listened to a socket for a series of bytes that represented a command and on recieving called a method which parsed the incoming data and invoked the appropriate command?
Clarification:
My issue is not with handling the commands (Which might also be error codes or responses to commands from the server) but with creating the socket and listening to it.
More Clarification:
What I want to do is mimic the following line of .Net (C#) code:
_stream.BeginRead(_data,0, _data.Length, new
AsyncCallback(this.StreamEventHandler), _stream);
Where:
_stream is a network stream created from a socket
_data is an array of Byte of length 9
this.StreamHandler is a delegate (function pointer) which get executed when data is read.
I am rewriting a library from C# into Java and the component I am currently writing passes commands to a server over TCPIP but also has to be able to bubble up events/responses to the layer above it.
In C# this seems to be trivial and it's looking less and less so in Java.
Starting from my other answer: The specific part you request is the one that goes into the section: "Magic goes here". It can be done in ohh so many ways, but one is:
final InputStream in = socket.getInputStream();
// This creates a new thread to service the request.
new Thread(new Runnable(){
public void run(){
byte[] retrievedData= new byte[ITEM_LENGTH];
in.read(retrievedData, 0, ITEM_LENGTH);
in.close();
// Here call your delegate or something to process the data
callSomethingWithTheData(retrievedData);
}
}).start();
Have a small main method which sets up the socket and listens for incoming connections. Pass each connection to a worker object (possibly in its own thread).
The worker object should have two APIs: The server and the client. The client API gets a connection and reads data from it, the server API takes a connection and writes data to it.
I like to keep these two in a single class because that makes it much more simple to keep the two in sync. Use a helper class to encode/decode the data for transmission, so you have single point to decide how to transmit integers, commands, options, etc.
If you want to go further, define a command class and write code to serialize that to a socket connection and read it from it. This way, you worker objects just need to declare which command class they handle and the server/client API gets even more simple (at the expense of the command class).
I would
put each command into a class of its own, where each class implements a specific interface (e.g. Command)
create a Map<String,Command> which contains a lookup table from each command string to an instance of the class that implements that command
This should help.
Lesson 1: Socket Communications
The TCP connection provides you with one InputStream and one OutputStream. You could just poll the InputStream continuously for the next command (and its inputs) on a dedicated thread. ByteBuffer.wrap(byte[] array) may be useful in interpreting the bytes as chars, ints, longs, etc. You could also pass objects around using serialization.
Any naive approach most likely will not scale well.
Consider using a REST-approach with a suitable small web-server. Jetty is usually a good choice.
To create an listen to a socket, in a very naive way:
mServerSocket = new ServerSocket(port);
listening = true;
while (listening) {
// This call blocks until a connection is made
Socket socket = serverSocket.accept();
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
// Here you do your magic, reading and writing what you need from the streams
// You would set listening to true if you have some command to close the server
// remotely
out.close();
in.close();
socket.close();
}
Normally it is a good idea to delegate the processing of the input stream to some other thread, so you can answer the next request. Otherwise, you will answer all requests serially.
You also need to define some kind of protocol of what bytes you expect on the input and output streams, but from your question it looks like you already have one.
You could create an enum with one member per command
interface Comamnd {
// whatever you expect all command to know to perform their function
void perform(Context context);
}
enum Commands implements Command{
ACTIONONE() {
void perform(Context context) {
System.out.println("Action One");
}
},
ACTIONTWO() {
void perform(Context context) {
System.out.println("Action Two");
}
}
}
// initialise
DataInputStream in = new DataInputStream(socket.getInputStream());
// in a loop
byte[] retrievedData= new byte[ITEM_LENGTH];
in.readFully(retrievedData);
String command = new String(retrievedData, 0);
Commands.valueOf(command).perform(context);