客户端服务器 EOF 错误
Client Server EOF Error
我的应用程序使用 DataInputStream 和 DataOutputStream 在服务器和客户端之间进行通信。客户端将从网站向我的应用程序发出请求,因此我创建了一个测试客户端来测试可能来自该网站的输入。
我决定使用的方法是客户端先发送一个整数,决定要发送的数据大小,然后再发送数据。因此,我正在测试此方法,它适用于第一个数据字符串,但不适用于第二个数据字符串,并且在第二次尝试时给了我一个 EOF 错误。我明白为什么它给了我一个 EOF,因为客户端关闭了连接,但我仍然没有读取传入的字节,所以流应该还有更多要读取的内容。
客户代码:
Socket socket = new Socket("127.0.0.1", 9000);
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
os.writeInt("Test String".length());
os.write("Test String".getBytes());
os.flush();
os.writeInt("String".length());
os.write("String".getBytes());
os.flush();
os.close();
socket.close();
服务器代码:
byte[] data;
try{
DataInputStream input = new DataInputStream(client.getInputStream());
DataOutputStream output = new DataOutputStream(client.getOutputStream());
client.setSoTimeout(SOCKET_TIMEOUT);
logger.log(Level.INFO, "Client connected with IP: " + client.getInetAddress());
data = readNextPacket(input);
if(!(new String(data).contains(PROTOCOL_HEADER)))
throw new IOException("Invalid request from client.");
else
logger.log(Level.INFO, "Valid header: " + new String(data));
data = readNextPacket(input);
logger.log(Level.INFO, new String(data));
}catch(IOException e){
logger.log(Level.SEVERE, e.getMessage(), e);
}finally{
try {
client.close();
} catch (IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
logger.log(Level.INFO, "FINISHED");
}
readNextPacket 方法:
private byte[] readNextPacket(DataInputStream stream) throws IOException{
int bytesToRead = stream.readInt();
ByteArrayOutputStream os = new ByteArrayOutputStream();
if(bytesToRead <= MAX_BYTES){
byte[] data = new byte[bytesToRead];
while(stream.read(data) != -1 && os.size() < bytesToRead){
os.write(data);
}
}
return os.toByteArray();
}
堆栈跟踪:
java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at com.schmidt73.bidwriter.handlers.SocketHandler.readNextPacket(SocketHandler.java:1)
at com.schmidt73.bidwriter.handlers.SocketHandler.parse(SocketHandler.java:16)
at com.schmidt73.bidwriter.handlers.SocketHandler.start(SocketHandler.java:43)
at com.schmidt73.bidwriter.BidWriter.main(BidWriter.java:21)
好吧,如果第一次没有读取整个缓冲区,基本上我的 readNextPacket()
方法会读取比指定的更多的数据。因此,我更改了一些代码以通过添加偏移量并减去我已经读取到 read()
方法的数量来修复它。但是,我意识到这基本上是在复制 readFully()
方法,没有理由这样做,所以我只是将其实现到 readNextPacket()
方法中。
这是新的工作代码:
private byte[] readNextPacket(DataInputStream stream) throws IOException{
int bytesToRead = stream.readInt();
byte[] data = new byte[bytesToRead];
stream.readFully(data);
return data;
}
我的应用程序使用 DataInputStream 和 DataOutputStream 在服务器和客户端之间进行通信。客户端将从网站向我的应用程序发出请求,因此我创建了一个测试客户端来测试可能来自该网站的输入。
我决定使用的方法是客户端先发送一个整数,决定要发送的数据大小,然后再发送数据。因此,我正在测试此方法,它适用于第一个数据字符串,但不适用于第二个数据字符串,并且在第二次尝试时给了我一个 EOF 错误。我明白为什么它给了我一个 EOF,因为客户端关闭了连接,但我仍然没有读取传入的字节,所以流应该还有更多要读取的内容。
客户代码:
Socket socket = new Socket("127.0.0.1", 9000);
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
os.writeInt("Test String".length());
os.write("Test String".getBytes());
os.flush();
os.writeInt("String".length());
os.write("String".getBytes());
os.flush();
os.close();
socket.close();
服务器代码:
byte[] data;
try{
DataInputStream input = new DataInputStream(client.getInputStream());
DataOutputStream output = new DataOutputStream(client.getOutputStream());
client.setSoTimeout(SOCKET_TIMEOUT);
logger.log(Level.INFO, "Client connected with IP: " + client.getInetAddress());
data = readNextPacket(input);
if(!(new String(data).contains(PROTOCOL_HEADER)))
throw new IOException("Invalid request from client.");
else
logger.log(Level.INFO, "Valid header: " + new String(data));
data = readNextPacket(input);
logger.log(Level.INFO, new String(data));
}catch(IOException e){
logger.log(Level.SEVERE, e.getMessage(), e);
}finally{
try {
client.close();
} catch (IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
logger.log(Level.INFO, "FINISHED");
}
readNextPacket 方法:
private byte[] readNextPacket(DataInputStream stream) throws IOException{
int bytesToRead = stream.readInt();
ByteArrayOutputStream os = new ByteArrayOutputStream();
if(bytesToRead <= MAX_BYTES){
byte[] data = new byte[bytesToRead];
while(stream.read(data) != -1 && os.size() < bytesToRead){
os.write(data);
}
}
return os.toByteArray();
}
堆栈跟踪:
java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at com.schmidt73.bidwriter.handlers.SocketHandler.readNextPacket(SocketHandler.java:1)
at com.schmidt73.bidwriter.handlers.SocketHandler.parse(SocketHandler.java:16)
at com.schmidt73.bidwriter.handlers.SocketHandler.start(SocketHandler.java:43)
at com.schmidt73.bidwriter.BidWriter.main(BidWriter.java:21)
好吧,如果第一次没有读取整个缓冲区,基本上我的 readNextPacket()
方法会读取比指定的更多的数据。因此,我更改了一些代码以通过添加偏移量并减去我已经读取到 read()
方法的数量来修复它。但是,我意识到这基本上是在复制 readFully()
方法,没有理由这样做,所以我只是将其实现到 readNextPacket()
方法中。
这是新的工作代码:
private byte[] readNextPacket(DataInputStream stream) throws IOException{
int bytesToRead = stream.readInt();
byte[] data = new byte[bytesToRead];
stream.readFully(data);
return data;
}