Problème avec Socket et GZIPInputStream
	
	
		Salut à tous,
j'essaie d'optimiser un programme assez conséquent qui a quelques problèmes de lag sur une fois sur internet. avant, a chaque envoi de message on créait une nouvelle socket, on envoyait un message et on attendait de recevoir l'acquittement...:calim2: j'essaie de simplifier tout ça en séparant les méthodes d'envoi réception à l'aide d'une classe SocketHelper
	Code:
	
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 
 | public class SocketHelper {
 
	private SSLSocket 	socket;
	private String		hostname;
	private int			port;
	private	int			timeOut;
 
	/**
         * SocketHelper constructor for clients
         * @param hostname
         * @param port
         * @param timeOut
         */
	public SocketHelper(String hostname, int port, int timeOut){
		try {			
			this.hostname 	= hostname;
			this.port 		= port;
			this.timeOut 	= timeOut;
			// SSL Socket
			SSLSocketFactory sslFact = (SSLSocketFactory) SSLSocketFactory.getDefault();
			socket = (SSLSocket) sslFact.createSocket(hostname, port);
			String set[] = new String[] { "SSL_RSA_WITH_NULL_MD5" };
			socket.setEnabledCipherSuites(set);
			socket.setReceiveBufferSize(48000);
			socket.setSendBufferSize(48000);
			socket.setTcpNoDelay(true);
			if (timeOut != 0)
				socket.setSoTimeout(timeOut);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
 
	/**
         * SocketHelper constructor for server (with accept)
         * @param sslSocket
         */
	public SocketHelper(SSLSocket sslSocket){			
		try {
			this.socket 	= sslSocket;
			this.hostname 	= socket.getInetAddress().getHostName();
			this.port 		= socket.getPort();
			this.timeOut 	= socket.getSoTimeout();
 
			String set[] = new String[] { "SSL_RSA_WITH_NULL_MD5" };
			socket.setEnabledCipherSuites(set);
			socket.setReceiveBufferSize(48000);
			socket.setSendBufferSize(48000);
			socket.setTcpNoDelay(true);
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}
 
	/**
         * Send compressed data
         * @param object
         * @return true if sent, else false
         */
	public boolean write(Object o){		
		if(socket != null && socket.isConnected() && !socket.isClosed()){
			try {
				OutputStream os = socket.getOutputStream();
				GZIPOutputStream gos = new GZIPOutputStream(os);
				BufferedOutputStream bos = new BufferedOutputStream(gos);
				ObjectOutputStream out = new ObjectOutputStream(bos);
 
				out.writeObject(o);
				out.flush();
				bos.flush();
				gos.finish();
 
				return true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
 
	/**
         * Read compressed data
         * @return object
         */
	public Object read(){
		if(socket != null && socket.isConnected() && !socket.isClosed()){
			try {
				InputStream is = socket.getInputStream();
				GZIPInputStream gis = new GZIPInputStream(is);
				BufferedInputStream bis = new BufferedInputStream(gis);
				ObjectInputStream in 	= new ObjectInputStream(bis);
				return in.readObject();
			} catch (EOFException e){
				System.out.println("debug : EOF on socket : "+hostname+":"+port);
				close();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
 
	/**
         * Close the socket
         * @return true if closed, else false
         */
	public boolean close(){
		if(socket != null){
			try {
				socket.close();
				return true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
 
	/**
         * Get the socket
         * @return socket
         */
	public Socket getSocket(){
		return socket;
	}
 
	/**
         * Get Remote Host Name attached to the socket
         * @return hostname
         */
	public String getHostname() {
		return hostname;
	}
 
	/**
         * Get Remote Port attached to the socket
         * @return
         */
	public int getPort() {
		return port;
	}
 
	/**
         * Get read time out (ms)
         * @return timeOut
         */
	public int getTimeOut() {
		return timeOut;
	}
 
	/**
         * Set the read time out (ms)
         * @param timeOut
         * @return
         */
	public boolean setTimeOut(int timeOut) {
		if(socket != null){
			try {
				socket.setSoTimeout(timeOut);
				this.timeOut = timeOut;
				return true;
			} catch (SocketException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
} | 
 J'essaie ensuite d'utiliser la même socket pour tous les échanges, avec un gestionnaire de requêtes traitant les messages reçus. (ClientThread).
Les classes qui ont besoin d'envoyer un message le font par appel a CMCThread.getInstance.write(...) et c'est le CMCThread qui leur renvoie la réponse éventuelle.
	Code:
	
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 
 |  
public class CMCThread extends Thread {
 
	private static CMCThread	_instance;
	private SocketHelper 		socketHelper;
	private LoginThread 		loginThread;
	private RealTimeThread		realTimeThread;
 
	private CMCThread(){
		socketHelper = new SocketHelper(Activator.getStringVal(CMCConfigKey.Server_IP),
				Integer.valueOf(Activator.getStringVal(CMCConfigKey.Server_Port)),
				3000);
		socketHelper.setForcedOnline(true);
	}
 
	public static CMCThread getInstance(){
		if(_instance == null)
			_instance = new CMCThread();
		return _instance;
	}
 
	public boolean write(Object o){
		return socketHelper.write(o);
	}
 
	public void setLoginThread(LoginThread lt){
		this.loginThread = lt;
	}
 
	public void setRealTimeThread(RealTimeThread rt){
		this.realTimeThread = rt;
	}
 
	public void run(){
 
		while(socketHelper.getSocket() != null){
			Object obj = socketHelper.read();
 
			if(obj instanceof LoginRequest){
				try {
					loginThread.receiveAnswer((LoginRequest) obj);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
 
			if(obj instanceof CRequest){
				switch(((CRequest) obj).getType()){
					case RequestConstants.AGENT_SEND_REALTIME_DATA :
						try {
							realTimeThread.passRequest((CRequest) obj);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						break;
					default :
						System.out.println("debug : received "+((CRequest) obj).getType());
						break;
				}
 
			}
		}
	}
} | 
 Je voudrais votre avis sur tout ça, car bien que ça aie l'air de marcher, j'ai un problème qui revient assez souvent (un message sur 15/20) :
	Code:
	
java.io.IOException: Not in GZIP format
 remonté par par le socketHelper.read de mon thread et plus précisément par cette ligne dans SocketHelper : GZIPInputStream gis = new GZIPInputStream(is);
J'ai vu quelques cas similaires sur internet mais je n'ai pas réussi à enlever ce problème ( qui n'éxistait pas en créant une socket à chaque envoi de message ) . J'ai réalisé la même chose dans les autres programmes (le serveur et un autre client) qui rencontrent le même problème alors que les messages n'ont pas changé !
Merci de votre aide !