向对等体发送消息的方法:
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的另一个实例读取时,Socket已关闭具有相同InputStream的BufferedReader。
发送的消息很好,并且适合此类的结构。
这是什么原因造成的?我怎样才能解决这个问题?
最佳答案
第一次在reader.ReadLine()
内部调用parseResponse()
时,BufferedReader
会从流中读取大量数据。它读取的不仅仅是一行,因为它尚不知道行尾在哪里。它从套接字读取(或删除)一行的唯一方法是逐个读取字符并在看到新行时停止。但这首先会破坏使用BufferedReader
的目的。
第二次在reader.ReadLine()
内部调用parseResponse()
时,它根本不会从基础套接字读取。它只是解析已经存储在BufferedReader
中的数据并返回下一行。
在parseResponse()
退出时,仍然在BufferedReader
内部存储了数据。当阅读器变量超出范围时,该数据将丢失。无法从套接字读取它,因为已经从套接字读取了它。
TLDR;
您可以在调试器中逐步浏览parseResponse()
,然后在 reader
实例内查看(检查JDK的内部数据结构)。您将在那里看到您的整个消息。并且您将看到parseResponse()
返回时,消息的其余部分如何丢失。
关于java - 从其InputStream读取后,套接字关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64249665/