结对编程队员
046 && 195
接口设计
客户端 用户登录后,启动一个线程来进行游戏,等待服务器信息及发送新数据
服务器 开始时,主程序一直等待用户登录,有新用户登录就开一个线程去为其服务
等到用户都登录完成,服务器开启一个游戏控制线程每隔1秒给全部用户发送一个“START” 信息,通知用户开始新的一轮开始,然后在0.5秒以后计算数据和分数,然后给全部用户发送这一轮结果。
服务器为每个用户都提供了一个服务线程,用于接收用户提交的数据
设计思路
本次设计 client/server 的程序是基于socket通信原理设计,具体如下:
Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。
其工作过程包含以下四个基本的步骤:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,服务器就会启动一个专门的服务线程来响 应该客户的请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。
server=new ServerSocket(6000); socket=new Socket(); System.out.println ("Server is beginning......"); while(true){ socket = server.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String userMess = br.readLine(); System.out.println(userMess); String[] mess = userMess.split(":"); System.out.println(userMess);
//登录 if(mess[3].equals(excel.getUserPassword(mess[1]))){ UserMessage userNew=new UserMessage(mess[1],mess[2],socket); if(addNewClient(userNew)){ PrintWriter pw=new PrintWriter(socket.getOutputStream()); pw.println("NORMAL"); pw.flush(); ServerThread thread=new ServerThread(userNew); thread.start(); System.out.println("电脑|" + dateString + "|登录成功|" + mess[1]); } else{ PrintWriter pw=new PrintWriter(socket.getOutputStream()); pw.println("ON"); pw.flush(); System.out.println("电脑|" + dateString + "|登录失败|" + mess[1]); } } else{ PrintWriter pw=new PrintWriter(socket.getOutputStream()); pw.println("NO"); pw.flush(); System.out.println("电脑|" + dateString + "|登录失败|" + mess[1]); } }
客户端向主机的某一个端口发出客户请求登陆服务器
try { serverip = InetAddress.getLocalHost().getHostAddress(); System.out.println(serverip); } catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }
}
客户端向服务器发送和接收信息
public String getMessage(String head,String username,String mess){ StringBuffer buffer=new StringBuffer(head+":"); buffer.append(username).append(":").append(mess); return buffer.toString(); } public void sendMessageToServer(String message){ try { PrintWriter pw=new PrintWriter(socket.getOutputStream()); pw.println(message); pw.flush(); }
每次游戏开始服务器启动一个TimerTask(),计算黄金点,并将各种数据返回到每一个客户端
if(newGame == 0){ for (int i = 0; i<list.size(); i++){ UserMessage user=(UserMessage)list.get(i); Socket sok=user.getSocket(); sentMessageToClient(sok,"START"); } newGame = 1; } else { turns++; System.out.println("turns = "+turns); newGame = 0; //计算G点 Gpoint = Sum/list.size()*0.618; System.out.println("Now Gpoint = "+Gpoint); //计算每个玩家分数 第一名加分 最后一面的减分 double xxx = 10000,max = 0,min = 100000; int best=0,sb=0; for (int i = 0; i<list.size(); i++){ UserMessage user=(UserMessage)list.get(i); xxx = Math.abs(user.submit - Gpoint); System.out.println(user.getName()+" "+user.submit+"-"+Gpoint); if(xxx > max){ sb =i; max = xxx; } if(xxx < min){ best =i; min = xxx; } } UserMessage sbuser=(UserMessage)list.get(sb); UserMessage bestuser=(UserMessage)list.get(best); sbuser.score -= 1; bestuser.score += 10; StringBuffer buffer=new StringBuffer(""); for (int j = 0; j<list.size(); j++){ UserMessage userx=(UserMessage)list.get(j); buffer.append(":"+userx.getName()+" "+userx.score); } for (int i = 0; i<list.size(); i++){ UserMessage user=(UserMessage)list.get(i); Socket sok=user.getSocket(); sentMessageToClient(sok,"GPOINT"+":"+turns+":"+Gpoint+buffer.toString()); } //游戏结束 if(turns == 10){ System.out.println("Game Over"); //输出用户得分 for (int i = 0; i<list.size(); i++){ UserMessage user=(UserMessage)list.get(i); System.out.println(""+user.getName()+" score is "+user.score); } this.cancel(); System.out.println("end?!"); } }