【发布时间】:2020-10-07 17:52:32
【问题描述】:
向对端发送消息的方法:
public static void writeLineToPeer(Peer peer, String message) throws IOException
{
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(peer.getSocket().getOutputStream(), StandardCharsets.UTF_8));
writer.write(message + "\n");
writer.flush();
}
阅读回复:
public class PeersResponse extends Response<Peer>
{
public PeersResponse(InputStream stream) throws InvalidMessageException, IOException
{
super(stream);
parseResponse();
getNextElement();
}
@Override
protected void parseResponse() throws InvalidMessageException, IOException
{
BufferedReader reader = new BufferedReader(new InputStreamReader(this.stream, "UTF-8"));
setVersion(reader.readLine());
setAmount(reader.readLine());
//Fine until here
}
@Override
public Peer getNextElement() throws InvalidMessageException, IOException
{
BufferedReader reader = new BufferedReader(new InputStreamReader(this.stream, "UTF-8"));
String ip = reader.readLine();
//Socket exception: Socket is closed
if (NetworkHelper.isValidIPAddress(ip))
{
throw new InvalidMessageException();
}
String port = reader.readLine();
String typeOfPeer = reader.readLine();
if (typeOfPeer.length() != 1)
{
throw new InvalidMessageException();
}
try
{
return PeerFactory.getPeer(typeOfPeer.charAt(0), ip, Integer.parseInt(port));
}
catch (Exception ex)
{
throw new InvalidMessageException(ex);
}
}
}
如您所见,我收到了一个 Socket 异常:尝试从另一个实例中读取时 Socket 已关闭 BufferedReader 具有相同的 InputStream。
正在发送的消息很好,适合这个类的结构。
这是什么原因?我该如何解决这个问题?
【问题讨论】:
-
我相信
this.stream在parseResponse()返回后将被关闭。您不应该在单个流上创建多个阅读器,您应该有一个实例级阅读器或PeersResponse的方法应该有一个BufferedReader reader参数。此外,BufferedReader#readLine可以返回null,如果没有内容可阅读,您应该检查null,以防出现格式错误的消息(尤其是关于if (typeOfPeer.length() != 1) // <-- NullPointerException)。 -
我尝试创建一个实例级阅读器并在
parseResponse()和getNextElement()上使用它,但我仍然遇到同样的异常。感谢您的提示,我将确保为空检查。 -
在这种情况下,接收到的消息一定有问题,或者您的代码的不同部分中的套接字发生了问题,此处未显示。您是否检查过
setVersion(...)和setAmount(...)的结果,如果它们设置为您所期望的? -
您可能应该使用相同的 BufferedReader 而不是重新创建它。你关闭它吗?关闭它会关闭底层的 inputStream。
标签: java sockets java-stream