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

Java Discussion :

Programmation concurrente client/serveur


Sujet :

Java

  1. #1
    Membre actif

    Inscrit en
    Août 2005
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 401
    Points : 228
    Points
    228
    Par défaut Programmation concurrente client/serveur
    Bonjour à tous,

    Je viens vous demander quelque renseignement à propos de la programmation concurrente. Je viens de développer un client et un serveur.

    Le client a 2 Thread et les deux communique avec le serveur. Le serveur a un thread pour chaque client. Mon problème réside dans le fait que je n'arrive pas à synchroniser le client et le serveur.

    Exemple :
    - Mon client communique avec le serveur via ces 2 threads parallèles, seulement certaines des requêtes qui doivent être envoyé au serveur ce mélange entre elle et pourtant j'ai mis des synchronized... J'utilise une Thread avec Runnable et un TimerTask sur le client.

    Sur le serveur j'ai aussi mis des synchronized sur la méthode qui gère les demande des clients et chaque thread dispose de son propre manager de requete. Le problème provient du client qui n'attends pas la finalité d'une requête. Une requête pour moi c'est :
    - une demande
    - un ou plusieurs envoie d'objet au serveur
    - un ou plusieurs envoie d'objet au client
    - un retour du server au client

    Voilà je ne sais pas trop ce que vous en pensez. J'attends des idées.

    Merci d'avance

  2. #2
    Membre actif

    Inscrit en
    Août 2005
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 401
    Points : 228
    Points
    228
    Par défaut
    Bonjour à tous,

    Je reviens vers vous car je suis toujours bloqué dans ma synchronisation... Donc je vous ajoute tout ce que j'ai sur le sujet... Je ne comprend pas pourquoi il y a des mélanges dans le NetworkManager.


    Alors voilà je préviens c'est un peu long. Mon objectif est de synchroniser mes requetes entre le client et le serveur afin qu'il n'y est pas de mélange de requête comme ci-dessous.

    Ma 1er Thread Cliente :
    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
    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
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
     
    package client;
     
    import game.GameManager;
    import game.player.Player;
    import game.player.PositionPlayer;
     
    import java.io.IOException;
    import java.util.Timer;
     
    import network.NetworkManager;
    import network.Request;
     
    import org.newdawn.slick.AppGameContainer;
    import org.newdawn.slick.SlickException;
     
    /**
     * Gestion d'une session cliente
     * 
     * @author akrogames
     * 
     */
    public class Client implements Runnable {
    	private GameManager gameManager;
    	private NetworkManager networkManager;
    	private Player player;
    	private Thread thread;
    	private Request request;
     
    	public Client() {
    		this.gameManager = new GameManager();
    		this.networkManager = new NetworkManager();
    		this.player = new Player(null, null);
    		this.thread = new Thread(this);
    		this.request = new Request();
    	}
     
    	@Override
    	public void run() {
    		// On lance les procedures de MAJ.
     
    		while(true) {
     
    		}
     
    	}
     
    	/**
             * Permet de lancer le jeu du client
             */
    	public void launchGame() {
    		AppGameContainer app;
    		try {
    			// On met à jour le player
    			player = (Player) networkManager.recvObject();
    			System.out.println("Bienvenue " + player.getName() + ", NUM: "
    					+ player.getNumPlayer());
    			System.out.println(player.getPositionPlayer().toString());
     
    			Timer time = new Timer();
    			ClientUpdate cu = new ClientUpdate(this);
    			time.schedule(cu, 0, 500);
     
    			// Creation du Thread de gestion du client
    			this.thread.start();
     
    			app = new AppGameContainer(new ClientGame(this));
    			app.setDisplayMode(1280, 640, false);
    	        app.start();
     
     
     
    		} catch (SlickException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
     
    	/**
             * Permet à un client de se connecter
             * 
             * @param identifiant
             * @param password
             * @return
             */
    	public int connexion(String identifiant, String password) {
    		Request r1 = null;
     
    		try {
    			networkManager.createSocket();
     
    			Player player = new Player(identifiant, password);
    			Request r = new Request(1, 2);
    			networkManager.sendRequest(r);
    			networkManager.objectOutput().writeObject(player);
    			networkManager.objectOutput().flush();
    			//networkManager.objectOutput().reset();
    			System.out.println("ENVOIE DU PLAYER OK");
     
    			r1 = (Request) networkManager.recvRequest();
    			System.out.println("RECEPTION du REQUEST");
     
    		} catch (IOException e) {
    			return -1;
    		}
     
    		if (r1.isAuthorized()) {
    			return 1;
    		} else {
    			networkManager.close();
    			return 0;
    		}
    	}
     
    	/**
             * On ferme les connexions
             */
    	public void close() {
    		networkManager.close();
    	}
     
    	public GameManager getGameManager() {
    		return gameManager;
    	}
     
    	public void setGameManager(GameManager gameManager) {
    		this.gameManager = gameManager;
    	}
     
    	public NetworkManager getNetworkManager() {
    		return networkManager;
    	}
     
    	public void setNetworkManager(NetworkManager networkManager) {
    		this.networkManager = networkManager;
    	}
     
    	public Player getPlayer() {
    		return player;
    	}
     
    	public void setPlayer(Player player) {
    		this.player = player;
    	}
     
    	public Thread getThread() {
    		return thread;
    	}
     
    	public void setThread(Thread thread) {
    		this.thread = thread;
    	}
     
    	/*******************************
             * Gestion des deplacements
             **********************************/
     
    	/**
             * Envoie la position du joueur au serveur
             * @throws IOException 
             */
    	synchronized public void updatePosition() {
    		this.request.setIdApplication(2);
    		this.request.setIdTypeReq(2);
    		try {
    			// Envoie de la requete cliente
    			this.networkManager.sendRequest(request);
     
    			// Envoie de la nouvelle position du joueur
    			System.out.println("ENVOIE "+this.getPlayer().getIdentifiant()+" POSITION : "+this.getPlayer().getPositionPlayer().getXRegion()+", "+this.getPlayer().getPositionPlayer().getYRegion());
    			this.networkManager.getOutputStream().writeObject(this.getPlayer());
    			this.networkManager.getOutputStream().flush();
     
    			this.networkManager.recvRequest();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
     
     
    	}
     
    	/**
             * Deplace en bas
             * @param x
             * @param y
             * @return
             */
    	public synchronized boolean deplaceBas(int x, int y) {
    		if(this.isBordBas(x, y)) {
    			this.getPlayer().getPositionPlayer().setYRegion(y++);
    			this.updatePosition();
     
    			return true;
    		}
    		else {
    			return false;
    		}
    	}
     
    	/**
             * Deplace en haut
             * @param x
             * @param y
             * @return
             */
    	public synchronized boolean deplaceHaut(int x, int y) {
    		if(this.isBordHaut(x, y)) {
    			this.getPlayer().getPositionPlayer().setYRegion(y--);
    			this.updatePosition();
     
    			return true;
    		}
    		else {
    			return false;
    		}
    	}
     
    	/**
             * 
             * @param x
             * @param y
             * @return
             */
    	public synchronized boolean deplaceGauche(int x, int y) {
    		if(this.isBordGauche(x, y)) {
    			this.getPlayer().getPositionPlayer().setXRegion(x--);
    			this.updatePosition();
     
    			return true;
    		}
    		else {
    			return false;
    		}
    	}
     
    	/**
             * 
             * @param x
             * @param y
             * @return
             */
    	public synchronized boolean deplaceDroite(int x, int y) {
    		if(this.isBordDroite(x, y)) {
    			this.getPlayer().getPositionPlayer().setXRegion(x++);
    			this.updatePosition();
     
    			return true;
    		}
    		else {
    			return false;
    		}
    	}
     
    	/**
             * Test des bords de la map
             * GAUCHE X -5
             * HAUT Y 1
             * DROITE X 1255
             * BAS Y 615
             * @return
             */
    	public boolean isBordBas(int x, int y) {
    		if(y > 615) {
    			return false;
    		}
    		else {
    			return true;
    		}
    	}
     
    	public boolean isBordHaut(int x, int y) {
    		if(y < 1) {
    			return false;
    		}
    		else {
    			return true;
    		}
    	}
     
    	public boolean isBordGauche(int x, int y) {
    		if(x < -5) {
    			return false;
    		}
    		else {
    			return true;
    		}
    	}
     
    	public boolean isBordDroite(int x, int y) {
    		if(x > 1255) {
    			return false;
    		}
    		else {
    			return true;
    		}
    	}
    }
    Ma classe cliente Slick2D :
    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
    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
    173
    174
    175
    176
    177
    178
     
    package client;
     
    import game.player.Player;
     
    import java.util.ArrayList;
     
    import org.newdawn.slick.Animation;
    import org.newdawn.slick.Color;
    import org.newdawn.slick.GameContainer;
    import org.newdawn.slick.Graphics;
    import org.newdawn.slick.Image;
    import org.newdawn.slick.Input;
    import org.newdawn.slick.SlickException;
    import org.newdawn.slick.SpriteSheet;
    import org.newdawn.slick.state.BasicGameState;
    import org.newdawn.slick.state.StateBasedGame;
     
    public class GameplayState extends BasicGameState {
    	private int stateID = -1;
    	private Client client;
    	private ArrayList<Player> players;
    	int x=0, y=0;
    	private Color background;
     
    	private Animation repos;
    	private Animation marchebas;
    	private Animation marchehaut;
    	private Animation marchedroite;
    	private Animation marchegauche;
    	private ClientMap mapregion;
     
    	private Animation reposPers1;
     
    	boolean marcheenbas = false;
    	boolean marcheenhaut = false;
    	boolean marcheagauche = false;
    	boolean marcheadroite = false;
     
    	public GameplayState(int stateID, Client c) {
    		this.stateID = stateID;
    		this.client = c;
    		this.x = this.client.getPlayer().getPositionPlayer().getXRegion();
    		this.y = this.client.getPlayer().getPositionPlayer().getYRegion();
    		this.players = this.client.getPlayer().getPositionPlayer().getPlayers();
    	}
     
    	@Override
    	public void init(GameContainer container, StateBasedGame state)
    			throws SlickException {
    		container.setVSync(true);
    		background = new Color(100, 110, 100);
     
    		mapregion = new ClientMap("data/region.tmx");
     
    		SpriteSheet sheet = new SpriteSheet("data/texture/perso.png",30,30);
    		SpriteSheet sheet1 = new SpriteSheet("data/texture/perso2.png",30,30);
    		repos = new Animation();
    		repos.setAutoUpdate(true);
    		repos.addFrame(sheet.getSprite(0, 0), 280);
    		repos.addFrame(sheet.getSprite(1, 0), 280);
    		repos.addFrame(sheet.getSprite(2, 0), 280);
     
    		marchebas = new Animation();
    		marchebas.setAutoUpdate(true);
    		for (int frame=0;frame<12;frame++) {
    			marchebas.addFrame(sheet.getSprite(frame,0), 280);
    		}
     
    		marchehaut = new Animation();
    		marchehaut.setAutoUpdate(true);
    		for (int frame=3;frame<12;frame++) {
    			marchehaut.addFrame(sheet.getSprite(frame,26), 280);
    		}
     
    		marchegauche = new Animation();
    		marchegauche.setAutoUpdate(true);
    		for (int frame=3;frame<8;frame++) {
    			marchegauche.addFrame(sheet.getSprite(frame,51), 280);
    		}
     
    		marchedroite = new Animation();
    		marchedroite.setAutoUpdate(true);
    		for (int frame=3;frame<8;frame++) {
    			marchedroite.addFrame(sheet.getSprite(frame,51), 280);
    		}
     
    		reposPers1 = new Animation();
    		reposPers1.addFrame(sheet1.getSprite(0, 0), 280);
     
    	}
     
    	@Override
    	public void render(GameContainer container, StateBasedGame state, Graphics graphic)
    			throws SlickException {
    		graphic.setBackground(background);
    		mapregion.render(0, 0);
     
    		// Personnage principale
    		if(marcheenbas) {
    			graphic.drawString(this.client.getPlayer().getName(), this.x-15, this.y-20);
    			graphic.drawAnimation(marchebas, this.x, this.y);
    		} else if(marcheenhaut) {
    			graphic.drawString(this.client.getPlayer().getName(), this.x-15, this.y-20);
    			graphic.drawAnimation(marchehaut, this.x, this.y);
    		} else if(marcheagauche) {
    			graphic.drawString(this.client.getPlayer().getName(), this.x-15, this.y-20);
    			graphic.drawAnimation(marchegauche, this.x, this.y);
    		} else if(marcheadroite) {
    			graphic.drawString(this.client.getPlayer().getName(), this.x-15, this.y-20);
    			graphic.drawAnimation(marchedroite, this.x, this.y);
    		}
    		else {
    			graphic.drawString(this.client.getPlayer().getName(), this.x-15, this.y-20);
    			graphic.drawAnimation(repos, this.x, this.y);
    		}
     
    		// autres personnage
    		for (Player p: this.client.getPlayer().getPositionPlayer().getPlayers()) {
    			//graphic.drawAnimation(reposPers1, 350, 350);
    			if(!p.getIdentifiant().equals(this.client.getPlayer().getIdentifiant())) {
    				graphic.drawAnimation(reposPers1, p.getPositionPlayer().getXRegion(), p.getPositionPlayer().getYRegion());
    				/*
    				System.out.println("-----------------------------------------");
    				System.out.println(p.getName()+", "+p.getPositionPlayer().getXRegion()+", "+p.getPositionPlayer().getYRegion());
    				System.out.println("-----------------------------------------");
    				*/
    			}
    		}
    	}
     
    	@Override
    	public void update(GameContainer container, StateBasedGame state, int delta)
    			throws SlickException {
     
     
    		// Gestion des touches directionelles
    		Input input = container.getInput();
    		input.disableKeyRepeat();
     
     
    		if (input.isKeyDown(Input.KEY_LEFT)) {
    			if(this.client.deplaceGauche(this.x, this.y)) {
    				this.x--;
    				marcheagauche = true;
    			}
    		} else if (input.isKeyDown(Input.KEY_RIGHT)) {
    			if(this.client.deplaceDroite(this.x, this.y)) {
    				this.x++;
    				marcheadroite = true;
    			}
    		} else if (input.isKeyDown(Input.KEY_UP)) {
    			if(this.client.deplaceHaut(this.x, this.y)) {
    				this.y--;
    				marcheenhaut = true;
    			}
    			else {
    				state.enterState(2);
    			}
    		} else if (input.isKeyDown(Input.KEY_DOWN)) {
    			if(this.client.deplaceBas(this.x, this.y)) {
    				this.y++;
    				marcheenbas = true;
    			}
    		} else {
    			marcheenbas = false;
    			marcheenhaut = false;
    			marcheagauche = false;
    			marcheadroite = false;
    		}
    	}
     
    	@Override
    	public int getID() {
    		return stateID;
    	}
     
    }
    Ma classe cliente TimerTask :
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    package client;
     
    import game.player.Player;
    import game.player.PositionPlayer;
     
    import java.io.IOException;
    import java.util.TimerTask;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
     
    import network.Request;
     
    public class ClientUpdate extends TimerTask {
    	private Request request;
    	private Client client;
     
    	private Lock lock;
     
    	public ClientUpdate(Client client) {
    		this.request = new Request();
    		this.client = client;
    		this.lock = new ReentrantLock();
    	}
     
    	public void run() {
     
    		//lock.lock();
     
    		this.updatePositionPlayers();
     
     
    		//lock.unlock();
     
    	}
     
    	public synchronized void updatePositionPlayers() {
    		// Mise a jour des joueurs de la region actuelle
    		request.setIdApplication(2);
    		request.setIdTypeReq(1);
    		client.getNetworkManager().sendRequest(request);
     
    		try {
    			// Envoie de la position du joueur
    			client.getNetworkManager().getOutputStream()
    					.writeObject(client.getPlayer().getPositionPlayer());
    			client.getNetworkManager().getOutputStream().flush();
     
    			// Reception du serveur
    			client.getPlayer().setPositionPlayer(
    					(PositionPlayer) client.getNetworkManager().recvObject());
     
     
     
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
     
    		/*
    		System.out.println("--------------------------------------------");
    		System.out.println("NBPLAYER dans la region : "
    				+ client.getPlayer().getPositionPlayer().getPlayers().size());
     
    		for (Player p : client.getPlayer().getPositionPlayer().getPlayers()) {
    			System.out.println("** " + p.getName()+", "+p.getPositionPlayer().getXRegion()+", "+p.getPositionPlayer().getYRegion());
    		}
     
    		System.out.println("--------------------------------------------");
    		*/
    	}
     
    }
    Mon NetworkManager sur le 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
    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
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
     
    package network;
     
    import game.GameManager;
    import game.player.Player;
    import game.player.PositionPlayer;
     
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.net.SocketAddress;
    import java.net.UnknownHostException;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
     
    /**
     * Gere la couche reseau du jeu côté client et côté serveur
     * 
     * @author akrogames
     * 
     */
    public class NetworkManager {
    	private GameManager gameManager;
    	private Socket socket;
    	private ObjectOutputStream outputStream;
    	private ObjectInputStream inputStream;
    	private Lock lock;
    	private Object object;
    	private Player joueur;
     
    	public NetworkManager() {
     
    	}
     
    	public NetworkManager(Socket socket, GameManager gameManager) {
    		this.socket = socket;
    		try {
    			this.outputStream = new ObjectOutputStream(
    					this.socket.getOutputStream());
    			this.inputStream = new ObjectInputStream(
    					this.socket.getInputStream());
    			this.gameManager = gameManager;
    			this.joueur = new Player(null, null);
    			this.object = new Object();
    			this.lock = new ReentrantLock();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
     
    	public GameManager getGameManager() {
    		return gameManager;
    	}
     
    	public void setGameManager(GameManager gameManager) {
    		this.gameManager = gameManager;
    	}
     
    	public Socket getSocket() {
    		return socket;
    	}
     
    	public void setSocket(Socket socket) {
    		this.socket = socket;
    	}
     
    	public ObjectOutputStream getOutputStream() {
    		return outputStream;
    	}
     
    	public void setOutputStream(ObjectOutputStream outputStream) {
    		this.outputStream = outputStream;
    	}
     
    	public ObjectInputStream getInputStream() {
    		return inputStream;
    	}
     
    	public void setInputStream(ObjectInputStream inputStream) {
    		this.inputStream = inputStream;
    	}
     
    	public Object getObject() {
    		return object;
    	}
     
    	public void setObject(Object object) {
    		this.object = object;
    	}
     
    	public Player getJoueur() {
    		return joueur;
    	}
     
    	public void setJoueur(Player joueur) {
    		this.joueur = joueur;
    	}
     
    	/**
             * Methode qui recoit des objets venant du client
             * 
             * @return
             */
    	public synchronized boolean serverManager() {
    		Request r;
    		try {
     
    			r = (Request) inputStream.readObject();
     
    			switch (r.getIdApplication()) {
    			// Application SYSTEME
    			case 1:
    				switch (r.getIdTypeReq()) {
    				// Récupération des mises a jours
    				case 1:
     
    					break;
    				// Connexion au réseau
    				case 2:
    					Player p = new Player(null, null);
    					p = (Player) inputStream.readObject();
    					boolean connexion = gameManager.connexionPlayer(p);
     
    					if (connexion) {
    						r.setAuthorized(true);
    					} else {
    						r.setAuthorized(false);
    					}
     
    					// Envoie de la confirmation de connexion
    					sendRequest(r);
    					System.out.println("Connexion joueur(" + p.getIdentifiant()
    							+ "): " + socket.getInetAddress().getHostAddress());
     
    					// Envoie du player avec les informations rempli
    					outputStream.writeObject(p);
    					outputStream.flush();
    					//outputStream.reset();
     
    					// Enregistrement du joueur dans le monde
    					joueur = p;
    					gameManager.addPlayer(p);
     
    					break;
    				default:
    					System.out.println("Requete systeme non reconnue");
    					break;
    				}
    				break;
    			// Application Social Empire
    			case 2:
    				switch (r.getIdTypeReq()) {
    				case 1:
    					// On recupere la position des joueurs de la region
    					joueur.setPositionPlayer((PositionPlayer) recvObject());
    					joueur.getPositionPlayer().setPlayers(
    							gameManager.getPlayerRegion(joueur
    									.getPositionPlayer()));
     
    					System.out.println("--------------------------------------------");
    					System.out.println("NBPLAYER dans la region : "
    							+ joueur.getPositionPlayer().getPlayers().size());
    					for (Player p : joueur.getPositionPlayer().getPlayers()) {
    						System.out.println("** " + p.getName()+", "+p.getPositionPlayer().getXRegion()+", "+p.getPositionPlayer().getYRegion());
    					}
    					System.out.println("--------------------------------------------");
     
    					// On renvoit la liste des joueurs dans la region et leurs position
    					outputStream.writeObject(joueur.getPositionPlayer());
    					outputStream.flush();
    					//outputStream.reset();
     
    					break;
    				case 2:
    					// On met à jour la position du joueur
    					this.setJoueur((Player) recvObject());
    					System.out.println("------------------------");
    					System.out.println("Player recu : "+this.getJoueur().getIdentifiant()+", "+this.getJoueur().getPositionPlayer().getXRegion()+", "+this.getJoueur().getPositionPlayer().getYRegion());
    					this.gameManager.updatePosition(this.joueur);
     
    					r.setAuthorized(true);
    					this.sendRequest(r);
     
    					break;
    				default:
    					System.out.println("Requete SE non reconnue");
    					break;
    				}
     
    				break;
    			// Application distributed computing
    			case 3:
     
    				break;
    			default:
    				System.out.println("Requete applicative non reconnue");
    				break;
    			}
    		} catch (IOException e) {
    			// Si on a un soucis ici il faut fermer la socket et sortir de la
    			// boucle
    			e.printStackTrace();
    			// Probleme de connexion on ferme tout
    			gameManager.delPlayer(joueur);
     
    			return false;
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			System.out.println("PROBLEME CLASS NOT FOUND");
    			e.printStackTrace();
    		}
     
    		return true;
    	}
     
    	/**
             * Methode qui permet de recevoir des objets du serveur
             */
    	public synchronized Object recvObject() {
     
    		try {
    			object = inputStream.readObject();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}
     
    		return object;
    	}
     
    	/**
             * Permet de creer une socket cliente
             * 
             * @todo changer le port et ladresse IP en consequence
             * @return
             * @throws UnknownHostException
             * @throws IOException
             */
    	public Socket createSocket() throws UnknownHostException, IOException {
    		int timeoutMs = 2000;
     
    		SocketAddress sockaddr = new InetSocketAddress("127.0.0.1", 20000);
    		socket = new Socket();
    		socket.connect(sockaddr, timeoutMs);
     
    		try {
    			outputStream = new ObjectOutputStream(socket.getOutputStream());
    			inputStream = new ObjectInputStream(socket.getInputStream());
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
    		return socket;
    	}
     
    	/**
             * Envoie l'objet Request
             * 
             * @param r
             */
    	public synchronized void sendRequest(Request r) {
    		try {
    			outputStream.writeObject(r);
    			outputStream.flush();
    			//outputStream.reset();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
     
    	/**
             * On recoit un objet request
             * 
             * @return
             */
    	public synchronized Request recvRequest() {
    		Request r = null;
    		try {
    			r = (Request) inputStream.readObject();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
    		return r;
    	}
     
    	public ObjectOutputStream objectOutput() {
    		return outputStream;
    	}
     
    	/**
             * On close la socket relier au NetworkManager
             */
    	public void close() {
    		try {
    			outputStream.close();
    			inputStream.close();
    			socket.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
     
     
     
    }
    La classe ServerThread qui gere le thread de chaque client :
    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
     
    package network;
     
    import game.GameManager;
    import game.player.Player;
     
    import java.net.Socket;
     
    public class ServerThread implements Runnable {
    	private Thread thread;
    	private Socket socket;
    	private Server server;
    	private NetworkManager networkManager;
     
    	public ServerThread(Socket socket, Server server) {
    		this.socket = socket;
    		this.server = server;
    		this.thread = new Thread(this);
    		this.thread.start();
    	}
     
    	public void run() {
    		boolean continu = true;
    		System.out.println("Tentative de connexion de: "
    				+ socket.getInetAddress().getHostAddress());
    		networkManager = new NetworkManager(socket, server.getGameManager());
     
    		while (continu) {
    			continu = networkManager.serverManager();
    		}
     
    		deconnexion();
    		// FIXME: can be done in deconnexion()
    		networkManager.close();
    	}
     
    	public void deconnexion() {
    		System.out.println("Deconnexion du client: "
    				+ socket.getInetAddress().getHostAddress());
     
    	}
     
    }

    Et l'erreur que j'obtiens du fait des plusieurs Thread qui mélange les requêtes entre elles...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Exception in thread "Thread-2" java.lang.ClassCastException: network.Request cannot be cast to game.player.Player
    	at network.NetworkManager.serverManager(NetworkManager.java:178)
    	at network.ServerThread.run(ServerThread.java:28)
    	at java.lang.Thread.run(Thread.java:679)

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Difficile de tout suivre dans le code, mais dans ton cas, si tu as du mélange, c'est que tes deux threads utilisent le même objectinputstream / objectoutputstream, ce qu'ils ne devraient pas!

    Aussi, le synchronized, ici, dans le client

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    synchronized public void updatePosition() {
    par exemple ne sert à rien. En effet, ça synchronize par rapport à l'instance et, chaque thread utilise, si je suis bien, une instance différente de Client => ca tourne toujours en parallèle. Ce qui ne devrais pas être un problème si chaque thread a bien sa propre connexion, comme mentionné plus haut.

  4. #4
    Membre actif

    Inscrit en
    Août 2005
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 401
    Points : 228
    Points
    228
    Par défaut
    Merci tchize de ta réponse. Je vais préciser des choses car oui c'est pas évident de suivre dans le code...

    En gros chaque client n'a qu'une Thread sur le serveur ! Mais le client a plusieurs Thread qui accède à l'unique Thread sur le serveur qui gère le client.

    De fait, il me parait normal d'avoir des objectinputstream / objectoutputstream identique sur les Thread clientes. Je me trompe ?

    En gros, pour éviter ce genre de problème de mélange, j'ai voulu attendre que le code qui envoie des requêtes au serveur se termine et cela devrait mettre en attente les autres Threads clientes et éviter les mélange mais sans succès pour le moment...

    Pour toi est-ce que mettre un reset dans les flux d'entrée ou de sortie et une aberration comme moi ? Est-ce qu'il est possible que ObjectInputStream garde en mémoire un objet précédent ?

    Je récapitule car c'est pas simple d'expliquer :
    - Le client à 3 Thread qui ont le même NetworkManager donc les même flux objectinputstream / objectoutputstream car ils sont relié à une unique socket au serveur.
    - Le serveur ne dispose que d'une Thread qui gère le client donc pas de problème de flux sur le serveur je pense.

    Tu en penses quoi ?

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Non, Chaque client a son propre flux dans le serveur. Le serveur obtiens le flux en retour de l'appel à socket.accept.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ServerSocket server = ....
    Socket client1 = server.accept()
    Socket client2 = server.accept()
    InputStream inputClient1 = client1.getInputStream()
    ...
    Et du coté client, chaque thread doit faire appel à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Socket client = new Socket(coordonnees du serveur)
    client.connect();
    client.getOutputStream()
    etc.

    Il n'y a rien de partagé, une paire client - server = 1 flux indépendant des autres.

  6. #6
    Membre actif

    Inscrit en
    Août 2005
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 401
    Points : 228
    Points
    228
    Par défaut
    Ah bon... je ne savais pas. Tu es sûr et certain qu'il est formellement interdit d'utiliser les mêmes flux pour des Threads différents ?

    Pour chaque Thread cliente il faut créer une nouvelle socket ? Cela signifie que chaque client va créer 3 Thread différent sur le serveur ?

    C'est hyper gourmand... Tu es sûr et certains ? Non pas que je remette en doute ton expérience en la matière mais je trouve cela étrange... Car si je lock correctement (Je ne sais pas comment...) les threads cliente ils doivent bien exécuter une seule opération à la fois non ?

    Donc si j'ai 30client sur le seveur j'ai 30*3 threads c'est juste énorme quoi...

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    C'est le plus facile. Avoir 90 thread sur le serveur n'est pas un problème. Si tu prend un serveur comme tomcat, par exemple, par défaut il accepte 128 thread en parallèle. Au delà, il met simplement les sockets en attente.

    Tu peux, évidement, composer ton protocole applicatif comme tu le veux, en ce et y compris autoriser plusieurs clients sur la même connexion, mais tu va rendre ton code plus complexe à lire et augmenter ta charge de travail pour pas grand chose. En tout cas, si tu commence à imbriquer plusieurs trucs comme ça, tu peux oublier les objectstream. De toutes façon, ce n'est pas vraiment idéal pour transférer de l'information entre un client et un serveur, surtout si les valeurs des objets changent au cours du temps.

    Les browser, en général, sont configuré pour avoir jusqu'à 16 connexion vers le même serveur.

Discussions similaires

  1. Réponses: 2
    Dernier message: 11/11/2013, 01h13
  2. Aide sur un programme Client Serveur
    Par clubmed01 dans le forum Linux
    Réponses: 33
    Dernier message: 29/05/2012, 10h22
  3. Programmation réseau client/serveur
    Par sophiesophie dans le forum Plateformes (Java EE, Jakarta EE, Spring) et Serveurs
    Réponses: 1
    Dernier message: 19/01/2010, 01h40
  4. Programmer un client/serveur
    Par horkets dans le forum Linux
    Réponses: 2
    Dernier message: 05/10/2006, 12h54
  5. architecture d'un programme client/serveur asynchrone (win)
    Par Heimdall dans le forum Développement
    Réponses: 2
    Dernier message: 05/09/2003, 23h59

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