IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

Problème avec serveur non bloquant


Sujet :

Entrée/Sortie Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 89
    Points : 90
    Points
    90
    Par défaut Problème avec serveur non bloquant
    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.

  2. #2
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Tu as bien pensé à rendre le Socket lisible dans doAcceptable que tu n'as pas mis ?

    (via client.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); )
    Je ne répondrai à aucune question technique en privé

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 89
    Points : 90
    Points
    90
    Par défaut
    Oui:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    			private void doAcceptable(SelectionKey myKey, Selector selector) throws IOException {
    				ServerSocketChannel myServerSocketChannel = (ServerSocketChannel)myKey.channel();
    				SocketChannel mySocketChannel = myServerSocketChannel.accept();
    				System.out.println(mySocketChannel.socket().getRemoteSocketAddress()+ " is now connected");
     
    				mySocketChannel.configureBlocking(false);
    				mySocketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(MAX_SIZE_BUFFER));
    			}
    Si un de vous veut bien mettre le nez dedans, j'ai créé un projet bidon qui utilise ces deux classes... Je peux vous les envoyer en PM.
    j'ai beau continuer a essayer de trouver le problème, mes efforts restent vains.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 89
    Points : 90
    Points
    90
    Par défaut
    Bon, j'ai trouvé le problème...
    Il s'agisait de la méthode d'envoi qui était fausse... Je m'adressais pas à la bonne socket.
    Erreur à la con!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [FLASH MX2004] [XMLSocket] Problème avec serveur socket php
    Par cocodunombril dans le forum Flash
    Réponses: 4
    Dernier message: 03/04/2009, 02h10
  2. Problème avec regex non trouvé
    Par Damien69 dans le forum Langage
    Réponses: 3
    Dernier message: 31/08/2008, 13h32
  3. [Tables Access] Problème avec AUTO_INCREMENT non reconnu
    Par GuixInDaMixx dans le forum VB.NET
    Réponses: 4
    Dernier message: 15/05/2008, 18h01
  4. Select avec écriture non bloquante
    Par Invité dans le forum Réseau
    Réponses: 5
    Dernier message: 24/05/2006, 16h20
  5. Problème de mutex avec Waitforsingleobject non-bloquant
    Par rvzip64 dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 03/11/2005, 11h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo