Java Réception et envoi des packets ?

Inscrit
22 Decembre 2014
Messages
3
Reactions
0
#1
Bonjour :)

Je viens ici à votre rencontre car je bute sur un problème depuis déjà un certain temps :( Pour vous expliquer rapidement, je reçois les packets, de une je suis pas certain de bien lire les valeurs stockées dedans et de deux je suis incapable d'y répondre ...

Je reçois un premier packets d'ID 1 :
Code:
|-----------------
|Reçu
|ID : 1
|Taille : 8 octets
|
|Contenu (bytes) : 
|[B@19723da7
|
|Contenu (héxadécimal) : 
|0 0 6 58 0 0 6 5A 
|
|Requis : 329728
|Actuel : 415744
|-----------------
Et quelques millièmes après je reçois le packet d'ID 3
Code:
|-----------------
|Reçu
|ID : 3
|Taille : 341 octets
|
|Contenu (bytes) : 
|[B@6805108d
|
|Contenu (héxadécimal) : 
|0 20 69 35 36 76 6D 35 71 78 51 7E 5D 79 30 59 29 57 3F 62 5D 6C 35 5B 71 3E 74 38 24 42 30 37 
|2A 22 1 31 1E 49 D5 AC 38 24 56 8 8B 3C AD 85 39 A3 61 50 1F B3 F8 CC 63 CF CF CA A3 6A 60 90 
|7E 78 2E C0 81 14 F1 56 E9 9D 7F E2 89 6F BA D5 1F 30 F4 3 D8 37 70 29 5 22 F3 41 6D 6 B6 8A 
|FB 42 EE F7 D9 51 F1 79 A9 7E 7A 1 7E 41 75 8D 5E B7 22 91 E9 9B 90 89 6E 8B 6D C3 2F DB EB 77 
|A3 2E 88 95 8D 0 6A 8D B2 A8 76 D2 4D FE 35 84 A9 26 E9 D2 4 6E FF 58 E0 63 59 8E DA 7D 99 DD 
|C0 4 B2 6E 21 33 EB DA B9 EF DB 5E 37 49 19 C6 F3 DF 9D C0 97 49 98 D4 E D9 2 83 A 37 DF D4 
|18 55 1 89 1C A1 41 70 D7 DC 9C 70 52 28 98 AF D1 9B D6 34 2D 18 E5 9A DD 23 11 52 AF 83 DE 2F 
|73 34 1E 5E F 12 76 7A 56 6C EA D3 66 B7 50 5D 34 6B 14 3A B A B9 67 35 ED 4B D3 27 68 63 54 
|7F 16 30 84 90 85 DE 73 5E AE 1E 34 61 73 9A 5E A4 38 6C A4 D2 C3 1F FD F6 FE DC 24 81 33 D6 66 
|DE AD B9 72 7D 88 FA B7 66 E3 23 F2 B 5B 9C E6 13 5A 86 DB 3B 96 6D F C E9 F5 2C 24 8E 2C 47 
|8E 29 E2 51 E1 81 50 51 78 C8 36 F0 54 46 45 F6 34 85 1 20 DF 
|
|Taille de la clé : 5
|
|Clé publique en byte : 
|[B@1794a43d
|
|Clé publique en clair : 
|8 0 0 6 58 
|-----------------
J'utilise la class DataReader/Writer de -débuter-dans-le-développement-socket-d2-(complet).162/]ce tutoriel que j'ai évidemment traduit du C# au Java. Sauf pour les variables de type "unsigned" qui n'existent pas en Java. Je vous les mettrais tout de même à la fin de ce post afin que vous puissiez éventuellement vérifier mon code ^-^

En ce qui concerne l'envoi du packet je le fais de cette matière :
Code:
DataWriter writer = new DataWriter();
                writer.writeByte(2);
                writer.writeByte(3);
                writer.writeByte(7);
                writer.writeShort(35100);
                writer.writeByte(0);
                writer.writeByte(0);
                writer.writeString("Ceciestjusteuntest");
                writer.writeString(password);
                writer.writeShort(0);
                writer.writeBoolean(true);
                
                OutputStream out = socket.getOutputStream();
                
                out.write(writer.pack(4));
                out.flush();
Sauf que, me semble t-il, depuis que ce tutoriel est en ligne la manière d'écrire le packet d'ID 4 a changée non ? Sachant que même après l'envoi je ne reçois aucune réponse du serveur, ni packet 20, ni packet 22, ni rien du tout en fait :(

Est-ce que l'un d'entre vous pourrait m'expliquer ce qui ne va pas dans mon code ? Merci d'avance :(

DataReader :
Code:
package fr.akabot.util;
 
public class DataReader 
{
	public int position = 0;
	public byte[] content;
	
	public DataReader(byte[] c) 
	{
		this.content = c;
	}
	
	public byte readByte() throws Exception
    {
        if (this.content.length >= 1)
        {
            byte result;
            result = this.content[position];
            this.position++;
            return result;
        }
        else
        {
            throw new Exception("Il n'y a plus d'octet à lire.");
        }
    }
	
	 public byte[] readBytes(int number) throws Exception
     {
         if (this.content.length >= number)
         {
             byte[] result = new byte[number];
             
             for (int i = 0; i != number; i++)
             {
                 result[i] = this.readByte();
             }
             
             return result;
         }
         else
         {
             throw new Exception("Il n'y a plus d'octets à lire.");
         }
     }
	 
	 public short readShort() throws Exception
     {
         if (this.content.length >= 2)
         {
             return (short)((this.readByte() << 8) + this.readByte());
         }
         else
         {
             throw new Exception("Il n'y a plus d'octets à lire.");
         }
     }
	 
	 public int readInt() throws Exception
     {
         if (content.length >= 4)
         {
             return (int)((readByte() << 24) + (readByte() << 16) + (readByte() << 8) + readByte());
         }
         else
         {
             throw new Exception("Il n'y a plus d'octets à lire.");
         }
     }
	 
	 public String readString() throws Exception
     {
         byte[] stringBytes = readBytes(readShort());
         return new String(stringBytes, "UTF-8");
     }
	 
	 public boolean readBool() throws Exception
     {
         if (readByte() == 01)
         {
             return true;
         }
         else
         {
             return false;
         }
     }
}
DataWriter :
Code:
package fr.akabot.util;

import java.util.ArrayList;
import java.util.List;

public class DataWriter 
{
	public List<Byte> content = new ArrayList<Byte>();
	
	public DataWriter()
	{
		
	}
	
	public int getLenghtType()
	{
		if(this.content.size() > Short.MAX_VALUE)
		{
			return 3;
		}
		else if(this.content.size() > Byte.MAX_VALUE)
		{
			return 2;
		}
		else if(this.content.size() > 0)
		{
			return 1;
		}
		
		return 0;
	}
	
	public short getHeader(int protocolID)
	{
		return (short)((protocolID << 2) | this.getLenghtType());
	}
	
	public byte[] pack(int protocolID)
	{
		int index = 0;
		int packetLenght = this.content.size();
		int packetLenghtType = this.getLenghtType();
		short packetHeader = this.getHeader(protocolID);
		
		byte[] packet = new byte[2 + packetLenghtType + packetLenght];
		packet[0] = (byte)(packetHeader >> 8);
        packet[1] = (byte)(packetHeader - 256 * packet[0]);
        
        switch (packetLenghtType)
        {
            case 1:
                packet[2] = (byte)(packetLenght);
                index = 3;
                break;
            case 2:
                packet[2] = (byte)(packetLenght >> 8);
                packet[3] = (byte)(packetLenght - 256 * packet[2]);
                index = 4;
                break;
            case 3:
                packet[2] = (byte)(packetLenght >> 16);
                packet[3] = (byte)(packetLenght >> 8);
                packet[4] = (byte)(packetLenght - 256 * packet[3] - 256 * 256 * packet[2]);
                index = 5;
                break;
        }
        
        for (int i = index; i < index + packetLenght; i++)
        {
            packet[i] = this.content.get(i - index);
        }
        
        return packet;
	}
	
	public void writeByte(int b)
	{
		this.content.add((byte) b);
	}
	
	public void writeShort(int s)
	{
		byte[] bytes = new byte[] {(byte) s,(byte) (s >> 8)};
		this.content.add(bytes[1]);
		this.content.add(bytes[0]);
	}
	
	public void writeInt(int i)
	{
		byte[] bytes = new byte[] {(byte) i, (byte) (i >> 8), (byte) (i >> 16), (byte) (i >> 24)};
		this.content.add(bytes[3]);
		this.content.add(bytes[2]);
		this.content.add(bytes[1]);
		this.content.add(bytes[0]);
	}
	
	public void writeString(String s)
	{
		this.writeShort((short) s.length());
		
		for(int i = 0 ; i < s.getBytes().length ; i++)
		{
			this.writeByte(s.getBytes()[i]);
		}
	}
	
	public void writeBoolean(boolean b)
	{
		if(b)
		{
			this.writeByte((byte) 01);
		}
		else
		{
			this.writeByte((byte) 00);
		}
	}
}
Reception (Thread qui reçois les packets du serveur et qui essaye de les envoyer pour le moment ...) :
Code:
package fr.akabot.threads;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import fr.akabot.util.AuthentificationSecurity;
import fr.akabot.util.DataReader;
import fr.akabot.util.DataWriter;

public class Reception implements Runnable 
{
	Socket socket;
	
	public Reception(Socket socket)
	{
		this.socket = socket;
	}
	
	public void run() 
	{
		try 
		{
			reception();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}
	
	public void reception() throws IOException
	{
		while(!this.socket.isClosed())
		{
			InputStream data = socket.getInputStream();
			
	        int available = data.available();
	        byte[] buffer = new byte[available];
	         
	        if(available > 0)
	        {
	        	data.read(buffer, 0, available);
	        	parseDataByte(buffer, 0);
	        }
	    }
		
		socket.close();
	}
	
	public void threatPacket(short packetID, byte[] buffer)
	{
		DataReader reader = new DataReader(buffer);
		
		if(packetID == 1)
		{
			try 
			{
				pr("Requis : " + reader.readInt(), true);
				pr("Actuel : " + reader.readInt(), true);
			} 
			catch (Exception e) 
			{
				e.printStackTrace();
			}
		}
		
		if(packetID == 3)
		{
			try
			{
				short keySize = reader.readShort();
				byte[] key = new byte[keySize];
				
				for(int i = 0 ; i < keySize ; i++)
				{
					key[i] = reader.readByte();
				}
				
				pr("Taille de la clé : " + keySize, true);
				pr("", true);
				pr("Clé publique en byte : \n|" + key + "\n|", true);
				pr("Clé publique en clair : \n|" + this.bytesToString(key, "%X", true, 32), true);
				
				pr("|\n|Préparation à l'envoi d'un packet ...");
				
				String password = AuthentificationSecurity.MD5(AuthentificationSecurity.MD5(Authentification.password) + this.bytesToString(key, "%X", false, Integer.MAX_VALUE));
				
				DataWriter writer = new DataWriter();
                writer.writeByte(2);
                writer.writeByte(3);
                writer.writeByte(7);
                writer.writeShort(35100);
                writer.writeByte(0);
                writer.writeByte(0);
                writer.writeString(Authentification.username);
                writer.writeString(password);
                writer.writeShort(0);
                writer.writeBoolean(true);
                
                OutputStream out = socket.getOutputStream();
                
                out.write(writer.pack(4));
                out.flush();
                
                pr("|\n|Packet envoyé ...");
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		
		if(packetID == 20)
		{
			pr("Authentification échouée.");
		}
		
		if(packetID == 22)
		{
			pr("Authentification réussie !");
		}
	}
	
	public void parseDataByte(byte[] buffer, int index) 
	{
		short packetID = (short)((buffer[index] * 256 + buffer[index + 1]) >> 2);
		short packetLengthType = (short)((buffer[index] * 256 + buffer[index + 1]) & 3);	
		int posLenght = index + 2;
		int posDatasMessage = packetLengthType + posLenght;
		int packetLenght = bytesToInt(posLenght, packetLengthType, buffer);
		byte[] content = subTabBytes(posDatasMessage, packetLenght, buffer);
		String contentHexa = bytesToString(content, "%X", true, 32);		
		pr("|-----------------\n|Reçu\n" + "|ID : " + packetID + "\n|Taille : " + packetLenght + " octets" + "\n|\n|Contenu (bytes) : \n|" + content + "\n|\n|Contenu (héxadécimal) : \n|" + contentHexa + "\n|");
		
		this.threatPacket(packetID, buffer);
		
		pr("|-----------------\n");

		if(packetLenght + posDatasMessage < buffer.length)
			parseDataByte(buffer, packetLenght + posDatasMessage);
	}
	
	public int bytesToInt(int posStart, int nbBytes, byte[] datas)
	{
		int result = 0;
		
		for(int i = posStart; i < nbBytes + posStart; i++)
		{
			if(i < nbBytes + posStart - 1)
			{
				result += datas[i] * 256;
			}
			else
			{
				result += datas[i];
			}
		}
		
		return result;
	}
	
	public byte[] subTabBytes(int indexStart, int length, byte[] datas)
	{
		byte[] result = new byte[length];
		
		for(int i = 0; i < length; i++)
		{
			result[i] = datas[i + indexStart];
		}
		
		return result;      
	}
	
	public String bytesToString(byte[] bytes, String format, boolean spacer, int line) 
	{
		StringBuilder sb = new StringBuilder(bytes.length * 2);
		int index = 0;
		
		for (byte b : bytes) 
		{	
			if(index == line)
			{
				sb.append("\n|");
				index = 0;
			}
			
			index++;
			sb.append(String.format(format, b));
				
			if(spacer)
			{
				sb.append(" ");
			}
		}
			
		return sb.toString();
	}
	
	public static final void pr(Object o)
	{
		System.out.println(String.valueOf(o));
	}
	
	public static final void err(Object o)
	{
		System.err.println(String.valueOf(o));
	}
	
	public static final void pr(Object o, boolean b)
	{
		System.out.println((b ? "|" : "") + String.valueOf(o));
	}
	
	public static final void err(Object o, boolean b)
	{
		System.err.println((b ? "|" : "") + String.valueOf(o));
	}
}

A savoir également que j'ai utilisé une partie des codes de ce sujet pour essayer de tout faire fonctionner, en vain ...

Merci d'avance ! :)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#2
Inscrit
22 Decembre 2014
Messages
3
Reactions
0
#3
Euh de rien :p C'est normal d'être clair dans ses questions si on veut que les réponses soient claires aussi :3

Yep' c'est ce qu'il me semblait et c'est ce que je faisais, mais sa structure a changé entre celle du tutoriel et celle d'aujourd'hui, non ? J'ai du mal à comprendre la structure du packet en fait :?

D'accord merci, je note :)

C'est possible de t'ajouter sur Skype ? ^-^
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#4
Ajoute moi oui biensur.

Non la structure n'a pas changé.
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#5
Code:
|Taille de la clé : 5
|
|Clé publique en byte : 
|[B@1794a43d
|
|Clé publique en clair : 
|8 0 0 6 58
Deja de mémoire elle fais dans les 300 donc tu dois te tromper dans la lecture des données
 
Inscrit
1 Mai 2014
Messages
20
Reactions
0
#7
La clé publique pour le RSA se trouve dans les sources binaire du jeu en format PEM.
 
Haut Bas