为每个客户创建新线程

时间:2016-08-03 18:39:05

标签: java multithreading networking server client

我有一段代码将客户端连接到我的服务器。但是,每次我将客户端连接到服务器时,它都会控制同一个播放器而不是创建新播放器。我认为这是因为我没有为每个新客户创建一个新线程。如果有人可以告诉我如何使用我已编写的代码为每个加入的客户创建一个新线程。

import java.net.*;
import java.io.*;

public class Client extends PlayGame
{
   public static void main(String [] args)
   {
      //String serverName = args[0];
      //int port = Integer.parseInt(args[1]);

      String serverName = "localhost";
      int port = 40004;

      //while (true ) {
          try
          {
             System.out.println("Connecting to " + serverName + " on port " + port);
             Socket client = new Socket(serverName, port);
             System.out.println("Just connected to " + client.getRemoteSocketAddress());

             OutputStream outToServer = client.getOutputStream();
             DataOutputStream out = new DataOutputStream(outToServer);
             //out.writeUTF("Hello from " + client.getLocalSocketAddress());


             //DataInputStream in = new DataInputStream(inFromServer);
             //System.out.println("Server says " + in.readUTF());


            PlayGame game = new PlayGame();
            //System.out.println("Do you want to load a specitic map?");
            //System.out.println("Press enter for default map");
            //game.selectMap(game.readUserInput());
            //System.out.println("You may now use MOVE, LOOK, QUIT and any other legal commands");
            String input = game.readUserInput();

            while (input != "quit") {
                out.writeUTF( input );

                InputStream inFromServer = client.getInputStream();
                DataInputStream in = new DataInputStream(inFromServer);

                System.out.println("Server Response:\n" + in.readUTF());

                input = game.readUserInput();
            }
            //game.update();


             //client.close();

          }catch(IOException e)
          {
             e.printStackTrace();
          }
      //}
   }
}      

服务器类和ClientThread子类

import java.net.*;
import java.util.Random;
import java.io.*;

public class Server implements IGameLogic
{
    private ServerSocket serverSocket;

    private Map map = null;
    private int[] playerPosition;
    private int collectedGold;
    private boolean active;

    public Server(int port) throws IOException
    {
       serverSocket = new ServerSocket(port);
       //serverSocket.setSoTimeout(10000);
    }

       public void startServer()
       {
          map = new Map();
          setMap(new File("example_map.txt"));
          System.out.println("Game Started - Map Initialized");

          while(true)
          {
             try
             {
                System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");

                Socket server = serverSocket.accept();

                ClientThread ct = new ClientThread(server, this );
                ct.start();



             }catch(SocketTimeoutException s)
             {
                System.out.println("Socket timed out!");
                break;
             }catch(IOException e)
             {
                e.printStackTrace();
                break;
             }
          }
       }



       public void setMap(File file) {
            map.readMap(file);
            playerPosition = initiatePlayer();
            active = true;
        }

        /**
         * Prints how much gold is still required to win!
         */
        public synchronized String hello() {
            return "GOLD: " + (map.getWin() - collectedGold);
        }

        /**
         * By proving a character direction from the set of {N,S,E,W} the gamelogic 
         * checks if this location can be visited by the player. 
         * If it is true, the player is moved to the new location.
         * @return If the move was executed Success is returned. If the move could not execute Fail is returned.
         */
        public synchronized String move(char direction) {

            int[] newPosition = playerPosition.clone();
            switch (direction){
            case 'N':
                newPosition[0] -=1;
                break;
            case 'E':
                newPosition[1] +=1;
                break;
            case 'S':
                newPosition[0] +=1;
                break;
            case 'W':
                newPosition[1] -=1;
                break;
            default:
                break;
            }

            if(map.lookAtTile(newPosition[0], newPosition[1]) != '#'){
                playerPosition = newPosition;

                if (checkWin())
                    quitGame();

                return "SUCCESS";
            } else {
                return "FAIL";
            }
        }

        public synchronized String pickup() {

            if (map.lookAtTile(playerPosition[0], playerPosition[1]) == 'G') {
                collectedGold++;
                map.replaceTile(playerPosition[0], playerPosition[1], '.');
                return "SUCCESS, GOLD COINS: " + collectedGold;
            }

            return "FAIL" + "\n" + "There is nothing to pick up...";
        }

        /**
         * The method shows the dungeon around the player location
         */
        public synchronized String look() {
            String output = "";
            char [][] lookReply = map.lookWindow(playerPosition[0], playerPosition[1], 5);
            lookReply[2][2] = 'P';

            for (int i=0;i<lookReply.length;i++){
                for (int j=0;j<lookReply[0].length;j++){
                    output += lookReply[j][i];
                }
                output += "\n";
            }
            return output;
        }

        public boolean gameRunning(){
            return active;
        }   


        /**
         * Quits the game when called
         */
        public void quitGame() {
            System.out.println("The game will now exit");
            active = false;
        }

        /**
         * finds a random position for the player in the map.
         * @return Return null; if no position is found or a position vector [y,x]
         */
        private int[] initiatePlayer() {
            int[] pos = new int[2];
            Random rand = new Random();

            pos[0]=rand.nextInt(map.getMapHeight());
            pos[1]=rand.nextInt(map.getMapWidth());
            int counter = 1;
            while (map.lookAtTile(pos[0], pos[1]) == '#' && counter < map.getMapHeight() * map.getMapWidth()) {
                pos[1]= (int) ( counter * Math.cos(counter));
                pos[0]=(int) ( counter * Math.sin(counter));
                counter++;
            }
            return (map.lookAtTile(pos[0], pos[1]) == '#') ? null : pos;
        }

        /**
         * checks if the player collected all GOLD and is on the exit tile
         * @return True if all conditions are met, false otherwise
         */
        protected boolean checkWin() {
            if (collectedGold >= map.getWin() && 
                    map.lookAtTile(playerPosition[0], playerPosition[1]) == 'E') {
                System.out.println("Congratulations!!! \n You have escaped the Dungeon of Dooom!!!!!! \n"
                        + "Thank you for playing!");
                return true;
            }
            return false;
        }

       public static void main(String [] args)
       {
          //int port = Integer.parseInt(args[0]);
          int port = 40004;

          try
          {
             //Thread t = new Server(port);
             //t.start();

             Server s = new Server(port);
             s.startServer();

          }catch(IOException e)
          {
             e.printStackTrace();
          }
       }
}

class ClientThread extends Thread {

    //private byte[] data = new byte[255];

      //private Socket socket;
      private Socket _socket;
      private Server _server;

      public ClientThread(Socket socket, Server s) {

        // for (int i = 0; i < data.length; i++)
        // data[i] = (byte) i;
        this._socket = socket;
        this._server = s;
      }

      public void run() {
         /* try {
          OutputStream out = new BufferedOutputStream(socket.getOutputStream());
          while (!socket.isClosed()) {
            out.write(data);
          }
          socket.close();
        } catch (Exception e) {
        } */

    try{
          System.out.println("Just connected to " + _socket.getRemoteSocketAddress());

          while ( _server.gameRunning() ) {
            DataInputStream in = new DataInputStream(_socket.getInputStream());
            // System.out.println(in.readUTF());

            String input = in.readUTF();
            System.out.println("Received from client: " + input );

            DataOutputStream out = new DataOutputStream(_socket.getOutputStream());
                //out.("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!");

            if ( input.equals("LOOK") ) {

                //String output = look();
                System.out.println("LOOK" );
                out.writeUTF( _server.look() );

            } else if ( input.equals("HELLO") ) {
                System.out.println("HELLO");
                out.writeUTF( _server.hello() );

            } else if ( input.equals("PICKUP") ) {
                System.out.println("PICKUP");
                out.writeUTF( _server.pickup() );

            } else if ( input.equals("QUIT") ) {
                System.out.println("QUIT");
                _server.quitGame();
                out.writeUTF( "The game has completed" );

            } else if ( input.equals("MOVE N") ) {
                System.out.println("MOVE N");
                out.writeUTF( _server.move('N') );

            } else if ( input.equals("MOVE E") ) {
                System.out.println("MOVE E");
                out.writeUTF( _server.move('E') );

            } else if ( input.equals("MOVE S") ) {
                System.out.println("MOVE S");
                out.writeUTF( _server.move('S') );

            } else if ( input.equals("MOVE W") ) {
                System.out.println("MOVE W");
                out.writeUTF( _server.move('W') );

            } else {
                out.writeUTF("Invalid Command");
            }

          }
    }catch(IOException e){

        //ioex.printStackTrace();
        e.printStackTrace();
        //break;
    }

          //DataOutputStream out = new DataOutputStream(server.getOutputStream());
          //out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!");

          //server.close();  
      }


}

0 个答案:

没有答案