我试图实现一个允许交换文本和文件的聊天客户端服务器(在本地)。我利用java.security
和java.crypto
来实现混合加密(以及Swing工具)。
我以序列化的方式交换文本(使用ObjectInputStream
和ObjectOutputStream
),在消息中以byte[]
格式插入(在我使用适当的函数加密之后)(这是我的一个对象)创建并在套接字之间有效交换:
import java.io.Serializable;
public class Message implements Serializable{
private static final long serialVersionUID = 1L;
byte[] data;
Message(byte[] data){
this.data = data;
}
byte[] getData(){
return data;
}
}
聊天工作正常,直到我只交换Message
。现在我试图实现文件传输(首先我尝试实现从服务器到客户端的文件传输,没有加密),因此我拿了一个文件" selectedFile"使用FileChoser,我将其发送给客户,感谢ObjectOutputStream
的方法writeObject(selectedFile)
。在客户端,我识别到达的对象是File
还是Message
:
class ListenFromServer extends Thread{
public void run(){
while(true){
try{
if((Message.class.isInstance(sInput.readObject()))==true){ //I verify if the recived object belongs to Message class
m=(Message) sInput.readObject();//sInput is an instance of ObjectInputStream class, connected to client socket's InputeStream
decryptMessage(m.getData()); //function that decrypts the content of m and inserts the result in a String that after I append in a text area
}
else
{
File recivedFile= (File) sInput.readObject();
File saveFile=new File(path+"/"+ recivedFile.getName());
save(recivedFile,saveFile);//function that insert the recived file in a specific folder
System.out.println("file ricevuto");
}
} catch (ClassNotFoundException ex) {
System.out.println("INFO: Classe non trovata durante la lettura dell'oggetto Messaggio: " + ex.getMessage() + "\n");
} catch(IOException e){
System.out.println("Connection closed");
break;
}
catch(NullPointerException ne){
ne.printStackTrace();
ne.getCause();
System.out.println("Errore"+ ne.getMessage());
}
问题是客户端只收到两次服务器" sendFile"按钮,此外现在这个问题还涉及向客户端发送文本的操作,因为客户端仅在我发送两次时才接收Message
对象(我使用两种不同的方法发送Message
对象和{{ 1}} object)。
当我消除指令时,这个问题不会发生:
File
我问你如何克服这个问题,或者是否有更好的方法来区分接收中的文件和消息对象。
答案 0 :(得分:1)
sInput.readObject()
这是一个读取对象的命令。你按顺序给这个两次,这是两个读取不同对象的请求。
要解决此问题,只需阅读一次对象,测试对象的类型,并在适当的时候进行投射:
Object inputObject = sInput.readObject(); // Read the object once
if (inputObject instanceof Message) { // If the object is a message
Message m = (Message) inputObject; // cast as a Message
... // use the Message m
} else if (inputObject instanceof File) { // else if it's a file
File f = (File) inputObject; // cast as a File
... // use the File f
}