J'ai une tâche d'école, pour envoyer une image jpg, la diviser en groupes de 100 octets, la corrompre, utiliser une vérification CRC pour localiser les erreurs et retransmettre jusqu'à ce qu'elle soit finalement intégrée dans son forme originale.Problème de transfert d'image Java
Il est pratiquement prêt, mais quand je regarde les nouvelles images, elles apparaissent avec des erreurs.
J'apprécierais vraiment si quelqu'un pourrait regarder mon code ci-dessous et trouvez peut-être cette erreur logique que je ne comprends pas ce que le problème est que tout est ok: S
Pour le fichier avec toutes les données nécessaires y compris les photos et les modèles d'erreur on pourrait le télécharger à partir de ce lien: http: //rapidshare.com/#! télécharger | 932tl2 | 443122762 | Data.zip | 739
N'oubliez pas de changer les chemins dans le code pour les fichiers d'image et d'erreur.
package networks;
import java.io.*; // for file reader
import java.util.zip.CRC32; // CRC32 IEEE (Ethernet)
public class Main {
/**
* Reads a whole file into an array of bytes.
* @param file The file in question.
* @return Array of bytes containing file data.
* @throws IOException Message contains why it failed.
*/
public static byte[] readFileArray(File file) throws IOException {
InputStream is = new FileInputStream(file);
byte[] data=new byte[(int)file.length()];
is.read(data);
is.close();
return data;
}
/**
* Writes (or overwrites if exists) a file with data from an array of bytes.
* @param file The file in question.
* @param data Array of bytes containing the new file data.
* @throws IOException Message contains why it failed.
*/
public static void writeFileArray(File file, byte[] data) throws IOException {
OutputStream os = new FileOutputStream(file,false);
os.write(data);
os.close();
}
/**
* Converts a long value to an array of bytes.
* @param data The target variable.
* @return Byte array conversion of data.
* @see http://www.daniweb.com/code/snippet216874.html
*/
public static byte[] toByta(long data) {
return new byte[] {
(byte)((data >> 56) & 0xff),
(byte)((data >> 48) & 0xff),
(byte)((data >> 40) & 0xff),
(byte)((data >> 32) & 0xff),
(byte)((data >> 24) & 0xff),
(byte)((data >> 16) & 0xff),
(byte)((data >> 8) & 0xff),
(byte)((data >> 0) & 0xff),
};
}
/**
* Converts a an array of bytes to long value.
* @param data The target variable.
* @return Long value conversion of data.
* @see http://www.daniweb.com/code/snippet216874.html
*/
public static long toLong(byte[] data) {
if (data == null || data.length != 8) return 0x0;
return (long)(
// (Below) convert to longs before shift because digits
// are lost with ints beyond the 32-bit limit
(long)(0xff & data[0]) << 56 |
(long)(0xff & data[1]) << 48 |
(long)(0xff & data[2]) << 40 |
(long)(0xff & data[3]) << 32 |
(long)(0xff & data[4]) << 24 |
(long)(0xff & data[5]) << 16 |
(long)(0xff & data[6]) << 8 |
(long)(0xff & data[7]) << 0
);
}
public static byte[] nextNoise(){
byte[] result=new byte[100];
// copy a frame's worth of data (or remaining data if it is less than frame length)
int read=Math.min(err_data.length-err_pstn, 100);
System.arraycopy(err_data, err_pstn, result, 0, read);
// if read data is less than frame length, reset position and add remaining data
if(read<100){
err_pstn=100-read;
System.arraycopy(err_data, 0, result, read, err_pstn);
}else // otherwise, increase position
err_pstn+=100;
// return noise segment
return result;
}
/**
* Given some original data, it is purposefully corrupted according to a
* second data array (which is read from a file). In pseudocode:
* corrupt = original xor corruptor
* @param data The original data.
* @return The new (corrupted) data.
*/
public static byte[] corruptData(byte[] data){
// get the next noise sequence
byte[] noise = nextNoise();
// finally, xor data with noise and return result
for(int i=0; i<100; i++)data[i]^=noise[i];
return data;
}
/**
* Given an array of data, a packet is created. In pseudocode:
* frame = corrupt(data) + crc(data)
* @param data The original frame data.
* @return The resulting frame data.
*/
public static byte[] buildFrame(byte[] data){
// pack = [data]+crc32([data])
byte[] hash = new byte[8];
// calculate crc32 of data and copy it to byte array
CRC32 crc = new CRC32();
crc.update(data);
hash=toByta(crc.getValue());
// create a byte array holding the final packet
byte[] pack = new byte[data.length+hash.length];
// create the corrupted data
byte[] crpt = new byte[data.length];
crpt = corruptData(data);
// copy corrupted data into pack
System.arraycopy(crpt, 0, pack, 0, crpt.length);
// copy hash into pack
System.arraycopy(hash, 0, pack, data.length, hash.length);
// return pack
return pack;
}
/**
* Verifies frame contents.
* @param frame The frame data (data+crc32).
* @return True if frame is valid, false otherwise.
*/
public static boolean verifyFrame(byte[] frame){
// allocate hash and data variables
byte[] hash=new byte[8];
byte[] data=new byte[frame.length-hash.length];
// read frame into hash and data variables
System.arraycopy(frame, frame.length-hash.length, hash, 0, hash.length);
System.arraycopy(frame, 0, data, 0, frame.length-hash.length);
// get crc32 of data
CRC32 crc = new CRC32();
crc.update(data);
// compare crc32 of data with crc32 of frame
return crc.getValue()==toLong(hash);
}
/**
* Transfers a file through a channel in frames and reconstructs it into a new file.
* @param jpg_file File name of target file to transfer.
* @param err_file The channel noise file used to simulate corruption.
* @param out_file The name of the newly-created file.
* @throws IOException
*/
public static void transferFile(String jpg_file, String err_file, String out_file) throws IOException {
// read file data into global variables
jpg_data = readFileArray(new File(jpg_file));
err_data = readFileArray(new File(err_file));
err_pstn = 0;
// variable that will hold the final (transfered) data
byte[] out_data = new byte[jpg_data.length];
// holds the current frame data
byte[] frame_orig = new byte[100];
byte[] frame_sent = new byte[100];
// send file in chunks (frames) of 100 bytes
for(int i=0; i<Math.ceil(jpg_data.length/100); i++){
// copy jpg data into frame and init first-time switch
System.arraycopy(jpg_data, i*100, frame_orig, 0, 100);
boolean not_first=false;
System.out.print("Packet #"+i+": ");
// repeat getting same frame until frame crc matches with frame content
do {
if(not_first)System.out.print("F");
frame_sent=buildFrame(frame_orig);
not_first=true;
}while(!verifyFrame(frame_sent)); // usually, you'd constrain this by time to prevent infinite loops (in
// case the channel is so wacked up it doesn't get a single packet right)
// copy frame to image file
System.out.println("S");
System.arraycopy(frame_sent, 0, out_data, i*100, 100);
}
System.out.println("\nDone.");
writeFileArray(new File(out_file),out_data);
}
// global variables for file data and pointer
public static byte[] jpg_data;
public static byte[] err_data;
public static int err_pstn=0;
public static void main(String[] args) throws IOException {
// list of jpg files
String[] jpg_file={
"C:\\Users\\Stefan\\Desktop\\Data\\Images\\photo1.jpg",
"C:\\Users\\Stefan\\Desktop\\Data\\Images\\photo2.jpg",
"C:\\Users\\Stefan\\Desktop\\Data\\Images\\photo3.jpg",
"C:\\Users\\Stefan\\Desktop\\Data\\Images\\photo4.jpg"
};
// list of error patterns
String[] err_file={
"C:\\Users\\Stefan\\Desktop\\Data\\Error Pattern\\Error Pattern 1.DAT",
"C:\\Users\\Stefan\\Desktop\\Data\\Error Pattern\\Error Pattern 2.DAT",
"C:\\Users\\Stefan\\Desktop\\Data\\Error Pattern\\Error Pattern 3.DAT",
"C:\\Users\\Stefan\\Desktop\\Data\\Error Pattern\\Error Pattern 4.DAT"
};
// loop through all jpg/channel combinations and run tests
for(int x=0; x<jpg_file.length; x++){
for(int y=0; y<err_file.length; y++){
System.out.println("Transfering photo"+(x+1)+".jpg using Pattern "+(y+1)+"...");
transferFile(jpg_file[x],err_file[y],jpg_file[x].replace("photo","CH#"+y+"_photo"));
}
}
}
}