#java
#java
Вопрос:
я создаю серверно-клиентское приложение, в котором сервер отправляет PDF-файл всем подключенным клиентам. Проблема в том, что я получаю эту ошибку, и я искал решение, но не смог его получить. Это ошибка
java.io.StreamCorruptedException: invalid stream header: 75720002
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:782)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
at StudentThread.run(StudentThread.java:102)
Вот код отправки с сервера:
public void run()
{
try
{
String modifiedSentence;
in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
inFromServer = new BufferedReader(new InputStreamReader(System.in));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream())), true);
//String sentence;
System.out.println("TeachID. " id);
modifiedSentence = in.readLine();
System.out.println("Student " id " says:" modifiedSentence);
arrS=modifiedSentence.split(" ");
out.println("Hello " arrS[2] "," id);
studName=arrS[2];
((DefaultListModel) Teacher.made_list.getModel()).addElement(studName);
while( true )
{
modifiedSentence = in.readLine();
arrS=modifiedSentence.split(" ");
if(arrS[0].equals("AcceptFile"))
{
try
{
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
byte[] buffer = (byte[])ois.readObject();
String pic="copyServer" id ".pdf";
System.out.println(pic);
FileOutputStream fos = new FileOutputStream(pic);
fos.write(buffer);
fos.flush();
fos.close();
}
catch(Exception e)
{
System.out.println("Exception writing");
}
}
}
catch (IOException e)
{
}
finally
{
try
{
socket.close();
}
catch(IOException e)
{
}
}
}
public void sendF(String fn,Teacher teach)
{
try{
out.println("AcceptFile,");
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()) ;
FileInputStream fis = new FileInputStream(fn);
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
//ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()) ;
oos.writeObject(buffer);
oos.flush();
fis.close();
}
catch(Exception e){
e.printStackTrace();
}
}
public void sendThread(String elem, Teacher teach)
{
out.println(elem);
//System.out.println ("Thread id is " this.id);
System.out.println(this.socket.getInetAddress());
}
Вот клиент, получающий код:
public void run()
{
try
{
out=new PrintWriter(socket.getOutputStream(), true);
out.println("Hello Server " name ",");
String modifiedSentence;
BufferedReader inFromServer = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
modifiedSentence = inFromServer.readLine();
System.out.println( modifiedSentence );
arrT=modifiedSentence.split(",");
if(arrT[0].equals("Hello " name))
{
studId=Integer.parseInt(arrT[2]);
System.out.println("My Id=" studId);
}
while( true )
{
modifiedSentence = inFromServer.readLine();
System.out.println( modifiedSentence );
arrT=modifiedSentence.split(",");
if(arrT[0].equals("AcceptFile"))
{
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
byte[] buffer = (byte[])ois.readObject();
String pic="copyServer" studId ".gif";
System.out.println(pic);
FileOutputStream fos = new FileOutputStream(pic);
fos.write(buffer);
fos.flush();
fos.close();
}
}
}
catch( Exception e )
{
e.printStackTrace();
}
}
Комментарии:
1. используете ли вы поток сокетов вообще перед этими частями на сервере и / или клиенте?
2. да, я использую его как на клиенте, так и на сервере.
3. если вы используете его до опубликованных вами частей кода, то вы делаете что-то не так (вероятно, несбалансированное чтение / запись). мы не можем угадать.
4. да, я использую его для чтения и записи, но как они могут быть несбалансированными?
5. не могу знать, не видя кода
Ответ №1:
BufferedReader
может буферизировать больше данных из сокета, чем вы уже прочитали. Таким образом, на стороне клиента ваш заголовок byte[]
, вероятно, уже был прочитан и буферизован вашим inFromServer
средством чтения и не будет доступен вашему ObjectInputStream
.
Не делай ничего подобного. Либо выполняйте весь маршалинг «вручную» (используя пару PrintWriter
/ BufferedReader
), либо делайте все это с помощью сериализации объектов с помощью ObjectOutputStream
/ ObjectInputStream
.
Комментарии:
1. Итак, если я собираюсь использовать BufferedReader, поскольку именно его я использую для чтения выходных данных сервера, как использовать его для записи отправленного файла?
2. вам нужно будет сделать это вручную, если вы пойдете этим путем, т. Е., вероятно, сначала запишите размер файла (либо в виде int, либо в виде строки), затем байты, используя один из методов PrintWriter.write.
3. но PrintWriter записывает только символ, или int, или строку, и мне нужно записать байты или объект (файл pdf). Как это можно сделать?
4. PrintWriter не предназначен для этого. Если вы хотите это сделать, вам придется преобразовать ваши данные в массив символов, что, вероятно, не сработает. Таким образом, PrintWriter — не лучший вариант. Вам потребуется меньше работы, чтобы заставить ваш текущий код работать только с сериализацией.
5. @Mat вы имеете в виду использовать OBJECTИЗ входного потока?