当前位置: 首页 > 面试题库 >

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

安坚诚
2023-03-14
问题内容

我正在尝试以客户端/服务器方式制作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 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:ObjectOuputStreams和将其发送到连接的另一端ObjectInputStreams。使用这两个类,您可以通过流写入和读取对象。

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()以及何时使用的更多信息。



 类似资料:
  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • 问题内容: 我正在编写一个Java包,该包将由另一种语言(matlab)调用。如果我的matlab进程结束,我希望Java进程继续运行。每当MATLAB重新启动时,它都应该能够与现有的运行过程进行通信。因此,我认为我需要让Java应用程序通过客户端/服务器模型中的套接字进行通信。我设想具有一组简单的功能: startServer(主机,端口) runCommand(服务器,命令…) stopSer

  • 我有一个客户端和一个服务器。客户端在特定端口上绑定一个套接字,服务器向客户端发回一个新端口,客户端应在新端口号上绑定一个新套接字。 从主服务器线程开始,我启动一个线程,一旦服务器准备好并正在监听新端口,就向客户端发送消息,以便客户端可以尝试连接到新端口。来自子线程的管道没有将消息发送到客户端。所以客户端和服务器都冻结了,看起来像是死锁,但我不确定。客户端:系统中的这行代码。出来println(“来

  • 我正在编写一个客户机-服务器应用程序,但在使用命令模式时遇到了问题。在我的程序中,服务器从客户端接收字符串输入命令,在HashMap中为输入找到合适的命令,执行它并返回返回值。我在弄清楚如何编写需要不止一步的命令时遇到了问题(命令必须要求客户机提供额外的参数,然后应该返回最终结果)。 命令界面 服务器与客户端的通信 一步到位,毫无问题 我不知道如何编写一个命令,它需要一个额外的参数来执行,它不能在

  • 我是编码和Java的新手,我已经创建了一个简单的客户端-服务器程序,客户端可以请求一个文件。它的内容将显示在浏览器页面中,还有一些细节,如数据类型和长度。我现在有一个问题,我不确定如何在浏览器中显示正确连接的服务器响应,如“HTTP/1.1 200 OK”和关闭的连接,如“Connection: close”。我有一个处理响应的方法,如下所示: 对我如何做到这一点有什么建议吗?非常感谢。

  • 我是Java的新手,我正在尝试学习线程和套接字。所以决定按照官方的java教程制作简单的客户机-服务器应用程序。我的想法很简单--服务器等待连接,如果出现,它就用新的套接字、输入和输出生成新线程。客户端->建立连接;带有套接字、输入、输出和stdIn的新线程(读取行,然后发送到服务器)。但是我的代码出了点问题(不知道为什么)。连接已经建立,没有例外。谁能解释一下为什么不工作,如何修复它?您还可以对