Java BufferedReader读取行方法挂起并阻止程序
我正在尝试使用Java学习套接字,并成功地将数据发送到运行在我自己机器上的ServerSocket。当我尝试使用readline从这个套接字读取时(这样我就可以回显我自己发送的消息),我的程序挂起并且不会返回 代码如下:Java BufferedReader读取行方法挂起并阻止程序,java,sockets,Java,Sockets,我正在尝试使用Java学习套接字,并成功地将数据发送到运行在我自己机器上的ServerSocket。当我尝试使用readline从这个套接字读取时(这样我就可以回显我自己发送的消息),我的程序挂起并且不会返回 代码如下: public static void main(String[] args) throws UnknownHostException, IOException { TCPClient cli = new TCPClient("127.0.0.1", "15000");
public static void main(String[] args) throws UnknownHostException, IOException {
TCPClient cli = new TCPClient("127.0.0.1", "15000");
try {
cli.ostream.writeUTF("Teste");
String echo = cli.istream.readLine(); //it hangs in this line
System.out.println(echo);
}
public class TCPClient {
public DataOutputStream ostream = null;
public BufferedReader istream = null;
public TCPClient(String host, String port) throws UnknownHostException {
InetAddress ip = InetAddress.getByName(host);
try {
Socket socket = new Socket(host, Integer.parseInt(port));
ostream = new DataOutputStream(socket.getOutputStream());
istream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
TCPClient是我定义的一个类,所以在我的Homwork上使用swing之前,我可以在一个更简单的界面上测试我的程序。代码如下:
public static void main(String[] args) throws UnknownHostException, IOException {
TCPClient cli = new TCPClient("127.0.0.1", "15000");
try {
cli.ostream.writeUTF("Teste");
String echo = cli.istream.readLine(); //it hangs in this line
System.out.println(echo);
}
public class TCPClient {
public DataOutputStream ostream = null;
public BufferedReader istream = null;
public TCPClient(String host, String port) throws UnknownHostException {
InetAddress ip = InetAddress.getByName(host);
try {
Socket socket = new Socket(host, Integer.parseInt(port));
ostream = new DataOutputStream(socket.getOutputStream());
istream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
我的服务器非常简单。在建立连接之后,它进入这个循环并在这里停留,直到我关闭客户端(因为无限循环)。之后,一些异常处理会将其返回到连接开始之前的点
while(true){
String msg = istream.readLine();
System.out.println("Arrived on server: " + msg); //just works on debug
ostream.writeUTF("ACK: " + msg);
ostream.flush();
}
我不知道我错过了什么
PS:wierd的东西是,如果我调试服务器,我可以看到消息到达那里(例如,我可以打印它),但是如果我只运行此代码,这是不可能的。这有我忽略的并发关系吗
thx
这不应该包含一个新行吗?否则我认为读法会等待新行
另外,根据建议,您可以在写入ostream后尝试刷新它。writeUTF()不写一行。请参阅Javadoc。writeUTF()用于readUTF()。和读者一起使用的作家。因此,将DataOutputStream更改为BufferedWriter并调用write(),然后调用newline()。问题在于
readLine
尝试读取一行。它将不会返回该行,直到它确定已到达该行的末尾。这意味着它需要换行符或通信结束。由于服务器不发送任何换行符,也不关闭流,因此客户端会无限期地等待。服务器做什么?如果它对您的消息没有任何响应,或者没有刷新其写入,那么客户端当然会无限期地等待,直到服务器发送一行。我将使用服务器的无限循环编辑帖子,同时回显消息。Sostream是输出流。OP说服务器正确地接收到了这条消息。问题是客户端没有从服务器接收到答案。我刷新了ostream并在字符串中添加了“\n”,以前没有这样做。但是问题还是一样的!在ostream.writeUTF(“ACK:+msg”)中放入“\n”;工作。现在唯一的疑问是我的客户机上出现了两个不可打印的字符。它们可以是什么?你在一边用UTF写,在另一边用平台的默认编码读。始终使用书写器来书写字符。始终使用指定特定显式编码的OutputStreamWriter包装输出流。对读取执行相同的操作:始终使用读取器,并使用InputStreamReader包装输入流,该读取器指定相同的特定编码。@Thiago Moraes它们是Javadoc中记录的writeUTF()放在那里的长度词前缀。请看我的答案。现在它工作正常了。我使用OutputStreamWriter和BufferedReader。但我仍然必须从客户端和服务器发送“\n”,以便一切都能正常工作。“好的一面是,我在编码方面再也没有问题了。”蒂亚戈莫雷斯看到了我的答案。都在里面。真奇怪,你真的把这个标记为正确。我相信我理解你所说的,但是要考虑我不是母语为英语的人,所以我需要Unicode支持。在我的案例中,推荐的类的组合是什么?@ThiagoMoraes我有一个拼写错误。使用读卡器和写卡器并指定字符集。