Salutations,

je tente desesperement de mettre en place un système clients/serveur non bloquant. J'ai donc développé le code suivant coté serveur:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
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
	public boolean connect() {		
		try {
			selector = Selector.open();
			serverChannel.configureBlocking(false);			
			serverChannel.register(selector, SelectionKey.OP_ACCEPT);			
		} catch (IOException e) {
			return false;
		}
		thread = new Thread(){
			@Override public void run(){						
				while(true){
					try {
						selector.select();
						for(SelectionKey myKey : selector.selectedKeys()){
							if(myKey.isAcceptable())
								doAcceptable(myKey, selector);
							if(myKey.isValid() && myKey.isReadable())
								doReadable(myKey, selector);
							if(myKey.isValid() && myKey.isWritable())
								doWritable(myKey, selector);							
						}
						selector.selectedKeys().clear();
 
					} catch (IOException e) {
						// TODO Auto-generated catch block
						// connection ended by client
						e.printStackTrace();
					}
				}
			}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
			private void doWritable(SelectionKey myKey, Selector selector) throws IOException {				
				System.out.println("==> Writable");
				SocketChannel mySocketChannel = (SocketChannel) myKey.channel();
				ByteBuffer myByteBuffer = (ByteBuffer) myKey.attachment();
				myByteBuffer.flip();								
 
				int len = mySocketChannel.write(myByteBuffer);
				System.out.println("doWritable write : "+len);
 
				if(myByteBuffer.hasRemaining()){
					myByteBuffer.compact();
 
				}
				else{
					if(mySocketChannel.socket().isInputShutdown()){
						mySocketChannel.socket().close();
						myKey.cancel();
						//P2PNetwork.removeServerFromNetwork(mySocketChannel.socket().getInetAddress().getHostAddress());
					}
					else{
						myByteBuffer.clear();
						myKey.interestOps(SelectionKey.OP_READ);
					}
				}
				System.out.println("<== Writable");
			}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
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
			private void doReadable(SelectionKey myKey, Selector selector) throws IOException {
				System.out.println("==> Readable");
				SocketChannel mySocketChannel = (SocketChannel)myKey.channel();
				ByteBuffer myBBtoReceive = (ByteBuffer)myKey.attachment();
 
				try{
					int nb = mySocketChannel.read(myBBtoReceive);
 
						if( nb == -1){ // the stream is closed
							myKey.cancel();
							mySocketChannel.socket().getInputStream().close();
						}
						else if (nb > 0){
							String request = null;
							StringBuilder requestBuilder = new StringBuilder();
							byte[] tab = new byte[MAX_SIZE_BUFFER];
							myBBtoReceive.flip();
 
							for (int i = 0; i < myBBtoReceive.limit(); i++) {								
								requestBuilder.append((char)myBBtoReceive.get());
 
								if(requestBuilder.charAt(i) == '\n'){
									if(i>0 && requestBuilder.charAt(i-1)=='\r'){
										request = requestBuilder.toString();
										request = request.substring(0, request.length()-2);
										System.out.println("requete construite: "+request);
										break;
									}
								}
							}
							if(request != null){
								System.out.println("recu par le server: "+request);
								// Manage the request ...
								protocol.manageRequest(request, mySocketChannel.socket().getInetAddress(), mySocketChannel.socket().getPort(), null);								
								myBBtoReceive.compact();								
								myKey.interestOps(SelectionKey.OP_WRITE);
							}
							else
								System.err.println("requete rejetee: "+new String(myBBtoReceive.array()));
						}
				}catch (IOException e) {
					// TODO: handle exception					
					System.out.println("client perdu");
					myKey.cancel();
					mySocketChannel.close();					
					System.out.println("<==> Readable Exception");
				}
				System.out.println("<== Readable");
			}
Tout ca pour dire que j'arrive bien a me connecter à mon serveur, puis effectuer un premier dialogue (vérification de la version du client): le client envoie une requete, et le serveur répond.

Par contre, plus tard, j'effectue une autre requete via le client, bien recue par le serveur qui ne répond pas...

Voici la méthode utilisée pour répondre:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
	static public boolean reply(String message, String address){
		// TODO vérifier que ca marche, héhéhé
		try{
			InetAddress host =  InetAddress.getByName(address);
			message = message + "\r\n";
			for (SelectionKey key : selector.selectedKeys()) {
				SocketChannel sc = (SocketChannel) key.channel();
				
				// try to send message on connected socket
				if(sc.socket().getInetAddress().equals(host)){
					//ByteBuffer bf = (ByteBuffer)key.attachment();
					System.out.println(host+" est egal a "+sc.socket().getInetAddress());
					int len = sc.write(ByteBuffer.wrap(message.getBytes()));
					key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
					System.out.println("Caracteres envoyes: "+len+"   => "+message);
					return true;
				}
			}
		}
		catch(IOException e){
			System.out.println("Message "+message+" can't be send: "+e.getMessage());
			return false;
		}
		System.out.println("Message "+message+" has not be send: "+address+" is not found in the server list");
		return false;
	}
Je capte vraiment pas pourquoi ca marche pour le 1er dialogue, mais plus pour la suite. Le serveur tente bien de répondre car le write (ligne en rouge) retourne bien le nombre de caractères de la chaine a renvoyer.
Y'a surement un truc que j'ai pas capté, mais quoi? ^^

Merci d'avance pour votre aide.