0
這是一個任務我正在嘗試幾種不同的方法來處理:數據報傳輸後未能投射物體
我們使用UDP來模擬TCP。今天早些時候,我設法讓文件傳輸在UDP上工作,但是當然iy沒有檢查重新發送'段'的錯誤,所以我沒有試圖實現一個帶有ID和一些字節數據的消息類型類。
調試顯示我我正確地使我的消息對象,然後我使用公共字節[] serialize(Object obj)
將我的對象轉換爲UDP數據報傳輸的字節數組。
在接收端,當我將反序列化的對象轉換回消息時,它會崩潰。
CAST失敗
Message receiveMSG = null;
try {
receiveMSG = (Message)deserialize(receivedPacket.getData());
} catch (ClassNotFoundException ex) {
Logger.getLogger(UDPReceiver.class.getName()).log(Level.SEVERE, null, ex);
}
Deserialize方法
private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream b = new ByteArrayInputStream(bytes);
ObjectInputStream o = new ObjectInputStream(b);
return (Message)o.readObject();
}
任何人都可以找出爲什麼這個轉換回失敗的原因?謝謝。
消息類
public class Message implements Serializable {
private int segmentID;
private byte[] packet;
public Message(int segmentID, byte[] packet)
{
this.segmentID = segmentID;
this.packet = packet;
}
public int getSegmentID()
{
return segmentID;
}
public byte[] getPacket()
{
return packet;
}
}
UDPSENDER CLASS
public class UDPSender implements Sender{
private File theFile;
private FileInputStream fileReader;
private DatagramSocket datagramSocket;
private int fileLength, currentPos, bytesRead, toPort;
private byte[] msg, buffer;
private String toHost,initReply;
private InetAddress toAddress;
private int segmentID;
public UDPSender(InetAddress address, int port) throws IOException{
toPort = port;
toAddress = address;
msg = new byte[512];
buffer = new byte[512];
datagramSocket = new DatagramSocket();
datagramSocket.connect(toAddress, toPort);
segmentID = 0;
}
@Override
public void sendFile(File theFile) throws IOException{
// Init stuff
fileReader = new FileInputStream(theFile);
fileLength = fileReader.available();
System.out.println(" -- Filename: "+theFile.getName());
System.out.println(" -- Bytes to send: "+fileLength);
send((theFile.getName()+"::"+fileLength).getBytes());
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
datagramSocket.receive(reply);
if (new String(reply.getData(), 0, reply.getLength()).equals("OK"))
{
System.out.println(" -- Got OK from receiver - sending the file ");
int length;
while (currentPos<fileLength){
bytesRead = fileReader.read(msg);
Message message = new Message(1,msg);
send(serialize(message));
currentPos = currentPos + bytesRead;
}
System.out.println(" -- File transfer complete...");
}
else{System.out.println("Recieved something other than OK... exiting");}
}
private void send(byte[] message, int length) throws IOException {
DatagramPacket packet =
new DatagramPacket(message, length);
datagramSocket.send(packet);
}
private void send(byte[] message) throws IOException {
DatagramPacket packet =
new DatagramPacket(message, message.length);
datagramSocket.send(packet);
}
public byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream o = new ObjectOutputStream(b);
o.writeObject(obj);
return b.toByteArray();
}
}
UDPRECEIVER
public class UDPReceiver {
DatagramSocket socket;
String filename, initString;
byte[] buffer;
DatagramPacket initPacket, receivedPacket;
FileOutputStream fileWriter;
int bytesReceived, bytesToReceive;
public UDPReceiver(int port) throws IOException {
// Init stuff
socket = new DatagramSocket(port);
buffer = new byte[516];
System.out.println(" -- Ready to receive file on port: " + port);
initPacket = receivePacket();
initString = "Recieved-" + new String(initPacket.getData(), 0, initPacket.getLength());
StringTokenizer t = new StringTokenizer(initString, "::");
filename = t.nextToken();
bytesToReceive = new Integer(t.nextToken()).intValue();
System.out.println(" -- The file will be saved as: " + filename);
System.out.println(" -- Expecting to receive: " + bytesToReceive + " bytes");
send(initPacket.getAddress(), initPacket.getPort(), (new String("OK")).getBytes());
fileWriter = new FileOutputStream(filename);
while (bytesReceived < bytesToReceive) {
receivedPacket = receivePacket();
Message receiveMSG = null;
try {
receiveMSG = (Message)deserialize(receivedPacket.getData());
} catch (ClassNotFoundException ex) {
Logger.getLogger(UDPReceiver.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(receiveMSG.getSegmentID());
// System.out.println(bytesReceived);
// send(initPacket.getAddress(), initPacket.getPort(), (new String("OK")).getBytes());
}
System.out.println(" -- File transfer complete.");
}
public DatagramPacket receivePacket() throws IOException {
DatagramPacket packet =
new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
return packet;
}
public byte[] receiveData() throws IOException {
DatagramPacket packet =
new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
return packet.getData();
}
public void send(InetAddress recv, int port, byte[] message)
throws IOException {
DatagramPacket packet =
new DatagramPacket(message, message.length, recv, port);
socket.send(packet);
}
private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream b = new ByteArrayInputStream(bytes);
ObjectInputStream o = new ObjectInputStream(b);
return (Message)o.readObject();
}
}
好的,我終於調試了劇組失敗的原因。我沒有考慮到序列化對象的完整字節大小。我將接收緩衝區更改爲「607」,並且演員陣容正常工作。 – 2013-02-18 22:27:49