关于简单客户端服务器套接字应用程序的一些问题

发布于 2024-11-27 14:16:39 字数 1255 浏览 0 评论 0原文

我正在使用套接字编写一个简单的多线程客户端-服务器应用程序,并且有几个问题:

  1. 对于客户端来说,真的有必要使用单独的线程来从服务器接收数据吗?

我发现的许多资源都使用客户端对象将数据(使用 dataOutputStream)发送到服务器,同时使用单个线程专门从服务器接收数据(使用 dataInputStream)。据推测,这是因为 I/O 流本质上是阻塞的,因此单个执行线程在等待服务器消息时不应该能够发送数据(或执行其他任何操作),因为程序会被阻塞,直到收到某些内容。

但是,我编写的客户端可以在不使用单独线程的情况下进行发送和接收。接收数据的代码(即socket.readUTF())放在while循环中,发送数据的代码(即socket.writeUTF())位于actionPerformed()方法中(当用户单击按钮时触发) )。据我所知,当用户什么也没做时,程序执行仍然在 while 循环中,监听服务器消息。当用户单击按钮时,会触发 actionPerformed() 方法,“中断”while 循环并发送消息。完成后,程序返回聆听。发送和接收工作完美。

那么为什么人们要使用单独的线程呢?

  1. 如果我决定使用单独的线程来接收,我是否也需要使客户端对象成为一个线程?或者我可以将客户端作为对象运行吗?我问这个是因为我注意到有些人将客户端对象作为线程运行。

我不太清楚他们为什么这样做,因为据我所知,当您创建一个对象和一个线程时,它们会同时运行(即就像两个线程一样)。由于这种情况下只涉及一个对象(客户端),因此它不需要作为线程运行,对吧?或者我错过了什么?

  1. 如果该方法是同步的,那么对象是否需要获取锁才能访问自己的方法?这是我的情况:

我的服务器是作为对象实现的。为每个客户端连接创建会话线程。每个会话线程每当收到客户端请求时都会调用服务器对象的handle()方法。 handle方法是同步的,并向客户端发送返回信息。

除了handle()方法之外,服务器还有一些其他方法向每个客户端发送信息。这些方法可以随时通过服务器的 GUI 调用(它们不是由会话线程调用)。当handle()方法运行时,我不希望这些其他方法运行,因为它们可能会干扰handle()并弄乱发送协议。换句话说,我希望在运行其他方法之前完成处理方法。

我可以使这些方法同步,以防止服务器对象在句柄方法运行时调用它们,反之亦然吗?理论上,服务器对象需要等待句柄的锁被释放,然后才能调用它们。我只是不确定对象(不是线程)是否需要获取其自己的同步方法上的锁才能访问它。因此我的问题。

很抱歉不够简洁,但我想尽可能清楚。非常感谢您的解释和反馈。

提前致谢。

I am writing a simple multithreaded client-server application using sockets, and have a few questions:

  1. For the client, is it really necessary to use a separate thread for receiving data from server?

Many resources I found use the client object to send data (using dataOutputStream) to the server, while employing a single thread specifically to receive data (using dataInputStream) from the server. This is supposedly because I/O streams are blocking by nature, so a single thread of execution shouldn't be able to send data (or do anything else) while waiting for a server message because the program is blocked until something is received.

However, the client I wrote could do sending and receiving without using a separate thread. The code to receive data (i.e. socket.readUTF()) was put in a while loop, and the code to send data (i.e. socket.writeUTF()) was in the actionPerformed() method (to be triggered when user clicked a button). As far as I can tell, while the user did nothing, program execution remained in the while loop, listening for server message. When the user clicks the button, the actionPerformed() method was triggered, "interrupting" the while loop and sending a message. Once done, the program went back to listening. The sending and receiving worked perfectly.

Why then do people use a separate thread?

  1. If i decide to use a separate thread for receiving do I need to make the client object a thread as well? Or can I just run the client as an object? I'm asking this because I noticed some people ran the client object as a thread.

I'm not too sure why they did that because as far as I can tell, when you create an object and a thread, they run concurrently (i.e. like two threads would). Since only one object is involved in this case (the client), it shouldn't need to be run as a thread, right? Or am I missing something?

  1. Does an object need to acquire the lock in order to access its own method, if that method is synchronized? Here's my situation:

My server is implemented as an object. Session threads are created for each client connection. Each session thread calls the server object's handle() method whenever it receives a client request. The handle method is synchronized, and sends return information to the client.

Apart from the handle() method, the server also has some other methods that send information to each client. These methods can be called at any time through the server's GUI (they are not called by the session threads). While the handle() method is running, I DO NOT want these other methods to run because they may interfere with handle() and mess up the sending protocol. In other words, I want the handle method to finish before these other methods are run.

Can I make these methods synchronized in order to prevent the server object from calling them when the handle method is running, and vice versa? Theoretically the server object would need to wait for the handle's lock to be released before it could call them. I'm just not sure if an object (not thread) would need to acquire the lock on its own synchronized method in order to access it. Hence my question.

Sorry for the lack of brevity, but I wanted to be as clear as possible. Explanations and feedback are very much appreciated.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终难遇 2024-12-04 14:16:39

发送&接收工作正常,因为您使用的是 swing 应用程序。 Swing 应用程序作为线程启动执行的任何操作都是 EventListener 线程的一部分(虽然我不太确定线程的确切名称)

..每当用户想要向服务器发送某些内容时,它都会使用事件侦听器线程来完成这项工作。这就是为什么您没有看到程序滞后的原因。

也可能是传输量不太大而不会占用时间。

如果您需要构建线程访问控制,您应该尝试阅读有关 ReentrantLocks 的内容,这些类是 JDK 的一部分。我建议您阅读《Java 并发实践》,以更好地了解 Java 线程。

一些链接可以帮助你解决这个问题
1. 可重入锁
2. Java并发实践

The Sending & receiving works fine because you are using a swing application. a swing app is started as a thread & any actions performed are a part of the EventListener thread (i'm not quite sure of the exact name of the thread though)..

you have a while loop runnung in a thread & whenever a user wants to send something to the server it uses the eventlistener thread to do the job.. Thats why you don't see the program lagging..

It could also be that the transfer isn't too large to take up time.

if you need to build thread access control you should try reading about ReentrantLocks, these classes come as part of JDK. i;d suggest you read Java Concurrency In practice to get a good understanding on java threading.

some links to help you with this
1. ReentrantLocks
2. Java Concurrency in Practice

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文