2011-11-29 88 views
0

我有三个类。当服务器启动时,它会创建一个带有guessCount和随机数的randomGame对象。当客户端启动时,它连接到服务器并将该号码传递给服务器以播放猜测方法(使用控制台输入号码)来猜测随机游戏生成的随机数。java多线程和对象

但是下面有问题。客户端每输入一次,guessCount &随机数就重新初始化(即随机数不同,guessCount不能递增)。我希望随机数对于每个运行的客户端程序都是相同的,并且每次猜测方法运行时,guessCount将会增加1。

public class Game { 
    private int num; 
    private int guessCount; 
    Game (int num) { 
     this.num = num; 

     System.out.println("guessCount = " + guessCount); 
     System.out.println("num = " + num); 
    } 

    public int guess (int ran) { 
     int result; 

     guessCount++; 
     if (this.guessCount >= 10) { 
      return -2; 
     } else if (ran < num) { 
      return -1; 
     } else if (ran > num) { 
      return 1; 
     } else { 
      return 0; 
     } 
    } 
} 

这里的RandomGame

class RandomGame extends Game { 
    RandomGame() {   
     super(0 + (int)(Math.random() * ((90 - (0)) + 1))); 
    } 

    public static void main (String args[]) { 
    } 
} 

这里的服务器:

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

public class Q4Server { 
    public static void main(String arg[]) { 
     try { 
      ServerSocket ss = new ServerSocket(12345); 
      while(true) { 
       Socket s = ss.accept(); 
       ClientHandler ch = new ClientHandler(s); 
       ch.start(); 
      } 
     } catch(IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 
} 

这里的客户端处理程序:

class ClientHandler extends Thread { 

    Socket socket; 
    RandomGame g; 

    public ClientHandler(Socket socket) { 
     this.socket = socket; 
     g = new RandomGame(); 
    } 

    public void run() { 
     try { 
      DataInputStream dis = new DataInputStream(socket.getInputStream()); 
      DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); 

      int x = dis.readInt();  

      int reply = this.g.guess(x); 
      System.out.println("reply = " + reply); 
      dos.writeInt(reply); 

      //System.out.println(reply); 
      //System.out.println(reply); 

      socket.close(); 
     } catch(IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 
} 

回答

0

你的问题是ClientHandler.run()方法。在退出之前,它应该循环3次(或者多次要求)猜测。你的套接字客户端也必须这样做。你有它目前的方式,客户端连接到服务器分别为每个猜测 - 没有“谈话”,这是你所需要的:

public void run() { 
    try { 
     final int guessMax = 3; 

     for (int i=0;i<guessMax;i++) { 
      DataInputStream dis = new DataInputStream(socket.getInputStream()); 
      DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); 

      int x = dis.readInt();  

      int reply = this.g.guess(x); 
      System.out.println("reply = " + reply); 
      dos.writeInt(reply); 
      dos.flush(); 

      //System.out.println(reply); 
      //System.out.println(reply); 
     } 

     socket.close(); 

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

希望有所帮助。

+0

没有影响:(....... – hkguile

0

尝试使用辛格尔顿RandomGame实例

0

你写

当服务器启动,它创建一个randomGame对象与guessCount 和随机数

你不这样做, ...每当客户端连接时创建该对象(在客户端处理程序构造函数中为每个客户端创建一个新的RandomGame对象)

你应该是对象的创建移到Q4server.main(...),并把它传递给所有的客户端处理程序(你将不得不改变构造函数签名,把它作为一个参数)

guessCount应该是挥发性

1

虽然@ DarkSquirrel42和@jowierun是正确的,我想扩大他们的答案,并提供另一种选择。

现在,客户端连接,创建新游戏,他们提供猜测,服务器回复并断开连接。当客户端再次连接时,他们会得到一个新的随机数字的新游戏。没有一个国家为客户端持有相同的游戏。

有这个问题3个可能的解决方案:

  1. 客户端可以保持连接到猜测的服务器。因此,当客户端最初连接并且客户端和服务器将在多次猜测时保持连接时,将选择随机数。这就是@ jowierun想要你做的事情。

  2. 客户端可以选择随机数并每次与服务器通信。所以客户端在连接时会写两个整数。但是这完全消除了对服务器的需求,这有点荒谬。

  3. 服务器可以在猜测之间为每个客户端保存状态。你可以通过几种不同的方式来做到这一点。服务器可以将与每个客户端的IP相关联的Game存储在Map中。这只有当每个IP有1个客户端时才有效。您可以从Socket获得IP。

    有一个问题是“超时”游戏。你不希望服务器永远缓存正在运行的游戏。也许每次连接服务器的客户端都可以查看游戏的Map并丢弃那些比某个时间段早的文件。您需要在游戏中添加一个createdMillis字段。

希望这会有所帮助。