【发布时间】:2014-01-23 06:56:48
【问题描述】:
我注意到,在一些用 Java 编写的 TCP 聊天程序的示例代码中,从客户端读取字符串和向服务器发送字符串都发生在 main.h 中。
例如,这里有一个教程,我看不到输入线程和输出线程之间的区别...http://www.cise.ufl.edu/~amyles/tutorials/tcpchat/TCPChat.java
“BufferedReader 输入”和“PrintWriter 输出”都与同一线程中的 TCP 套接字一起使用。作为一个完全的新手,这让我感到困惑,因为以前,如果我有一些等待输入的东西,比如从 C 中获取字符函数的“getch()”,那么那个东西会阻塞线程(除非它是一个事件或异常)。通常,当我想象线程中的代码正在执行时,我想象它是逐行执行的,偶尔会出现异常和事件的执行跳转。但是写入流和读取流既不是异常也不是事件——我不知道如果主线程接收到输入字符串并且应该同时发送输出字符串会做什么。流本身是否实际上由其他线程或其他程序(如终端或操作系统)处理?
我对此感到很奇怪,所以我将聊天程序分成两个单独的线程以让我感觉更舒服 - 一个线程用于从 TCP 套接字接收字符串,另一个线程用于通过同一个套接字发送字符串。有人可以解释为什么我将输入和输出分成两个单独的线程的行为是完全没有必要的吗?在有人因缺乏研究和理解而将其记下之前,我尽我所能阅读了有关套接字的在线 Java 教程,并且我有读写流(终端和纯文本文件)的经验。
【问题讨论】:
-
你能告诉我们你正在谈论的代码吗?出于您提到的原因,您应该为此需要单独的线程,除非您使用
select之类的东西来等待输入。 -
我看到创建了一个线程来处理 GUI,但我没有看到程序分成一个输入线程和另一个输出线程。
-
我相信一切都在第 455 行:
if (in.ready()) {根据BufferedReader javadoc,该调用表明以下读取是否不会阻塞。这样I/O线程就不会阻塞了。 -
您关于
ready()的说法是正确的。这是非常糟糕的技术:不要使用它。例如,如果发送方在没有行终止符的情况下发送数据,它仍然会阻塞。它似乎也在事件调度线程上执行网络操作。这是一部糟糕的作品。两个线程是更好的解决方案,或者使用 NIO 进行非阻塞 I/O。
标签: java c multithreading sockets tcp