制作客户端服务器java应用程序

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

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

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

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

你有这样的想法或例子吗? 如何编写服务器部分来处理客户端的请求?

提前致谢

Fluminis

我要解释TCP:
基本概念是您必须在计算机上运行“服务器”。 该服务器接受等待连接的客户端。 每个连接都通过一个端口(你知道,我希望……)。
始终使用1024以上的端口,因为低于1025的端口大部分时间是为标准协议(如HTTP(80),FTP(21),Telnet,…)保留的。

但是,使用Java创建服务器是这样做的:

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

如果你想做研究,“Socket”是你可能正在寻找的词。
要将客户端连接到服务器,您必须编写以下内容:

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

但现在,仍然没有联系。 服务器必须接受等待的客户端(我在上面注意到):

 Socket connectionToTheClient = server.accept(); 

完成! 您的连接已建立! 通信就像File-IO一样。 您唯一需要记住的是,您必须决定何时刷新缓冲区并真正通过套接字发送数据。
使用PrintStream进行文本编写非常方便:

 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. 

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

 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. 

希望您可以从这些信息的网络开始!
PS:当然,所有网络代码都必须为IOExceptions尝试。

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

 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(); 

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

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

  DataInputStream类。  的readLine() 

此方法不使用缓冲区并逐字节读取并检查换行符。 因此,此方法不会从底层InputStream中窃取字节。


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

 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); 

获得对象后,可以使用Serialization: ObjectOuputStreamsObjectInputStreams将其发送到连接的另一端。 通过这两个类,您可以通过流编写和读取对象。

 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. 

在连接的另一边:

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

(***) :查看我的问题 ,了解有关reset()以及何时使用它的更多信息。

Glassfish可能比你需要更多的火力,但我不会放弃利用现有的库。

套接字的一些选项:

  • SimpleJavaServer (GPL)
  • QuickServer (LGPL)
  • Netty (Apache)。

如果您决定更多地使用Web服务而不是套接字,那么Jetty就是采用小型HTTP的方法。

如果要编写简单的客户端服务器类型程序,可以按照本教程中给出的建议进行操作。

如果你想做一些更多的事情,就像你说的普通Java那样你可能需要看一下RMI 。

然而,现在, Web服务风靡一时,您可能会发现从长远来看它更简单。

  1. 确定您要提供的服务(loadThing,editThing,makeThingBelch)
  2. 决定通信/消息传递协议(http似乎很直接。)
  3. 实施服务,经常进行unit testing以确保它们正常工作。
  4. 现在开始编写客户端,请记住,您可能需要添加新服务或更改现有服务。

我想到的一件事是你为什么要用’简单的java’而不是使用现有的应用服务器来编写它? 一些EJB3用于抽象和管理通信,安全性,事务完整性等的东西?