做一个客户端服务器java应用 [英] make a client server java application

查看:130
本文介绍了做一个客户端服务器java应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图以客户端/服务器方式创建一个Java应用程序。
客户端是SWT中的一个GUI,显示来自服务器的数据。服务器连接到数据库。



好的,对不起,这是一个经典的问题,我敢肯定,但我不知道如何开始。 p>

在我工作的项目中,他们通过 Proxy.newProxyInstance()实现了很多魔法,以便透明地调用Glassfish服务器。



我不想使用Glassfish服务器。我只是想在简单的Java中的东西。但是代理的概念看起来很酷。



你有这样的想法或例子吗?



提前感谢



Fluminis

p>

解决方案

我要解释TCP:

基本概念是你必须运行Server 在机器上。该服务器接受等待连接的客户端。每个连接通过一个端口(你知道,我希望...)。

始终使用1024以上的端口,因为低于1025的端口是大多数时间为标准协议保留的(如HTTP(80) FTP(21),Telnet,...)



但是,在Java中创建服务器的方式是这样的:

  ServerSocket server = new ServerSocket(8888); // 8888是服务器将监听的端口。 

Socket是您想要研究的字词。

并且要连接您的客户端到服务器,你必须这样写:

  Socket connectionToTheServer = new Socket ,8888); //第一个param:服务器地址,第二个:端口

但是现在还没有连接。服务器必须接受等待的客户端(正如我在上面注意到的):

  Socket connectionToTheClient = server.accept 

完成!您的连接建立!通信就像File-IO。你唯一要记住的是,你必须决定什么时候刷新缓冲区并真正通过套接字发送数据。

使用PrintStream进行文本编写非常方便: / p>

  OutputStream out = yourSocketHere.getOutputStream(); 
PrintStream ps = new PrintStream(out,true); //第二个参数:auto-flush on write = true
ps.println(Hello,Other side of the connection!
//现在,你不必刷新它,因为我们打开了自动刷新标志。

用于文本阅读的BufferedReader是好的(最好的*)选项:

  InputStream in = yourSocketHere.getInputStream(); 
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = br.readLine();
System.out.println(line); //打印你好,连接的另一端!,在这个例子中(如果这将是连接的另一端)

$ b $希望你可以从这个信息开始联网!

PS:当然,所有网络代码都必须尝试捕获IOExceptions。



编辑:我忘了写为什么它不总是最好的选择。BufferedReader使用一个缓冲区,尽可能多地读入缓冲区,但有时你不希望BufferedReader在换行符之后窃取字节,并将它们放入自己的缓冲区。

简短示例:

  InputStream in = socket.getInputStream(); 
BufferedReader br = new BufferedReader(new InputStreamReader(in));
//另一边说hello:
String text = br .readLine();
//无论什么原因,你想从流中读取一个单字节,
//刚刚在换行之后的单字节:
byte b =(byte )in.read();

但是BufferedReader已经有了这个字节,他的缓冲区。因此,调用 in.read()将返回读取器缓冲区中最后一个字节后面的字节。



因此,在这种情况下,最好的解决方案是使用 DataInputStream 并以你自己的方式来管理它,知道字符串的长度,并只读取该字节数,并转换它们成字符串。或:您使用

 DataInputStream。 readLine() 

此方法不使用缓冲区,并逐字节读取并检查换行符。所以这种方法不会窃取底层InputStream的字节。






编辑:你可以开发自己的协议,您可以使用Java Reflexion请求方法调用。例如:

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

一旦你有了你的对象,你可以把它发送到连接的另一边,序列化: ObjectOuputStreams ObjectInputStreams 。使用这两个类,您可以通过流写入和读取对象。

  Object obj = ...; //你想要通过流写的对象。 (需要实现java.io.Serializable)
ObjectOutputStream oos = new ObjectOuptputStream(socket.getOutputStream());
oos.writeObject(oos);
oos.reset(); //(***)
//不要关闭它!否则连接也将关闭。

在连接的另一端:

  ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
Object object = ois.readObject(); //读取对象
//不要关闭它!
//然后将它转换为任何你想要的。

(***):有关的详细信息,请我的问题 reset()以及何时使用它。


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

解决方案

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.

这篇关于做一个客户端服务器java应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆