make a client server java application
Asked Answered
D

4

8

I am trying to make a Java application in a client/server way. The client is a GUI in SWT which displays data from the server. The server is connected to a database.

Ok, sorry for that, it's a classic question I'm sure, but I don't know how to start.

In a project I worked for they implemented a lot of magic with Proxy.newProxyInstance() to invoke the Glassfish server transparently.

I don't want to use a Glassfish server. I just want something simple in plain Java. But the concept of proxies seems pretty cool.

Do you have ideas or examples of such thing? How do I write the server part to handle the requests of clients?

Thanks in advance

Fluminis

Downrange answered 6/1, 2011 at 14:28 Comment(1)
I was going to suggest trying JMS Producer/Consumer approach but you want something plain.Champaigne
M
40

I'm going to explain TCP:
The basic concept is that you have to run a "Server" on a machine. That server accepts clients waiting for a connection. Each connection goes over a port (you know, I hope...).
Always use ports above 1024 because ports lower than 1025 are most of the time reserved for standard protocols (like HTTP (80), FTP (21), Telnet, ...)

However, creating a Server in Java is done this way:

ServerSocket server = new ServerSocket(8888); // 8888 is the port the server will listen on.

"Socket" is the word you are probably looking for if you want to do research.
And to connect your client to a server you have to write this:

Socket connectionToTheServer = new Socket("localhost", 8888); // First param: server-address, Second: the port

But now, there isn't still a connection. The server has to accept the waiting client (as I noticed here above):

Socket connectionToTheClient = server.accept();

Done! Your connection is established! Communicating is just like File-IO. The only thing you have to keep in mind is that you have to decide when you want to flush the buffer and really send the data through the socket.
Using a PrintStream for text-writing is very handy:

OutputStream out = yourSocketHere.getOutputStream();
PrintStream ps = new PrintStream(out, true); // Second param: auto-flush on write = true
ps.println("Hello, Other side of the connection!");
// Now, you don't have to flush it, because of the auto-flush flag we turned on.

A BufferedReader for text-reading is the good (best*) option:

InputStream in = yourSocketHere.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = br.readLine();
System.out.println(line); // Prints "Hello, Other side of the connection!", in this example (if this would be the other side of the connection.

Hopefully you can start with networking with this information!
PS: Of course, all networking code have to be try-catched for IOExceptions.

EDIT: I forgot to write why it isn't always the best option. A BufferedReader uses a buffer and read as much as it can into the buffer. But sometimes you don't want that the BufferedReader steals the bytes after the newline and put them into his own buffer.
Short example:

InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// The other side says hello:
String text = br.readLine();
// For whatever reason, you want to read one single byte from the stream,
// That single byte, just after the newline:
byte b = (byte) in.read();

But the BufferedReader has already that byte, you want to read, in his buffer. So calling in.read() will return the byte following on the last byte in the buffer of the reader.

So, in this situation the best solution is to use DataInputStream and manage it your own way to know how long the string will be and read only that number of bytes and convert them into a string. Or: You use

DataInputStream.readLine()

This method doesn't use a buffer and reads byte by byte and checks for a newline. So this method doesn't steal the bytes from the underlying InputStream.


EDIT: You can develop your own protocol in which you can request a method call using Java Reflexion. For example:

String className = ...;
String methodName = ...;
Class[] methodParamTypes = ...;
Object[] methodParams = ...;
Class cl = Class.forName(className);
Method me = cl.getDelcaredMethod(methodName, methodParamTypes);
Object returnValue = me.invoke(this, methodParams);

Once you have your object you can send it to the other side of the connection with Serialization: ObjectOuputStreams and ObjectInputStreams. With these two classes you can write and read objects through a stream.

Object obj = ...; // Your object you want to write through the stream. (Needs to implement java.io.Serializable)
ObjectOutputStream oos = new ObjectOuptputStream(socket.getOutputStream());
oos.writeObject(oos);
oos.reset(); // (***)
// Don't close it! Otherwise the connection will be closed as well.

And on the other side of the connection:

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object object = ois.readObject(); // Read the object
// Don't close it!
// Then cast it to whatever you want.

(***): Check out my question for further information about reset() and when to use it.

Mosenthal answered 6/1, 2011 at 14:37 Comment(6)
Thank you for your answer. I understand well with you example how to retrive text. But is it possible with soket to invoke a methode on the server and get complexe objet in return ?Downrange
Take a look at ObjectOutputStream and ObjectInputStream.Mosenthal
also, you might be thinking about java RMI (remote method invocation) - there's good documentation on it.Marx
Note: unix require you to be root to use <1024 ports. Windows has a more complex scheme, but usually allow it.Waylin
@ThorbjørnRavnAndersen: That is one of the first things I mentioned in my answer.Mosenthal
I am elaborating in the reason why it is so.Waylin
E
5

Glassfish may be more firepower than you need, but I wouldn't give up on leveraging an existing library.

Some options for sockets:

If you decide on going more towards web services than sockets, Jetty is the way to go for small footprint HTTP.

Exocentric answered 6/1, 2011 at 18:46 Comment(0)
S
3

If you want to write a simple client server type programme you can follow the advice given in this tutorial.

If you want to do something a bit more involved, in plain Java as you say then you may need to look at RMI.

However, these days, web services are all the rage and you may find that in the long run it is simpler.

Solecism answered 6/1, 2011 at 14:33 Comment(0)
D
1
  1. Identify the services you want to provide (loadThing, editThing, makeThingBelch)
  2. decide upon communication/messaging protocol (http seems straightfoward.)
  3. implement the services, unit testing frequently to make sure they work.
  4. NOW start writing the client, keeping in mind you might have to add new services or change existing ones.

One thing that comes to mind is why do you want to write it in 'simple java' rather than using an existing application server? some EJB3 thing to abstract and manage communication, security, transactional integrity, etc?

Demagogic answered 6/1, 2011 at 14:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.