打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
一个Java游戏服务器与对手间的通讯操作
userphoto

2017.04.04

关注
Java网络游戏中的服务端与对手通信的操作,本类中的构造函数利用一个网络站点名,打开一个套接字连接到对应主机上的端口如果成功,用InputStreamReader和BufferedReader包装输入,用PrintWriter包装输出。如果失败,向调用者引发一个异常。
view source
print?
001import java.io.*;
002import java.net.*;
003import java.util.*;
004/**
005 *  该类封装了与服务器和对手之间的通讯
006 **/
007class ServerConnection implements Runnable {
008  private static final int port = 6564;   // 端口号
009  private static final String CRLF = "\r\n";
010  private BufferedReader in;  // 与服务器间的I/O流
011  private PrintWriter out;
012  private String id, toid = null;  // 本地ID和对手ID
013  private Scrabblet scrabblet;
014  /** 构造函数利用一个网络站点名,打开一个套接字连接到对应主机上的端口
015   *  如果成功,用InputStreamReader和BufferedReader包装输入,用PrintWriter
016   *  包装输出。如果失败,向调用者引发一个异常
017   **/
018  public ServerConnection(Scrabblet sc, String site) throws IOException {
019    scrabblet = sc;
020    Socket server = new Socket(site, port);
021    in = new BufferedReader(new InputStreamReader(server.getInputStream()));
022    out = new PrintWriter(server.getOutputStream(), true);
023  }
024  private String readline() {
025    try {
026      return in.readLine();
027    } catch (IOException e) {
028      return null;
029    }
030  }
031  /** 该方法通知服务器本地游戏者的名字 */
032  void setName(String s) {
033    out.println("name " + s);
034  }
035  /** 该方法将自己从服务器的列表上删除 */
036  void delete() {
037    out.println("delete " + id);
038  }
039  /** 绑定对手的id */
040  void setTo(String to) {
041    toid = to;
042  }
043  void send(String s) {
044    if (toid != null)
045      out.println("to " + toid + " " + s);
046  }
047  // 下面的方法都是从客户端向服务器发送一行消息,然后服务器将这些消息
048  // 发送给对手。
049  /** challenge消息初始启动游戏 */
050  void challenge(String destid) {
051    setTo(destid);
052    send("challenge " + id);
053  }
054  /** accept消息用来响应挑战 */
055  void accept(String destid, int seed) {
056    setTo(destid);
057    send("accept " + id + " " + seed);
058  }
059  void chat(String s) {
060    send("chat " + id + " " + s);
061  }
062  /** 每次移动一个字母,发送一个move消息 */
063  void move(String letter, int x, int y) {
064    send("move " + letter + " " + x + " " + y);
065  }
066  /** 每次回合结束时发送turn消息 */
067  void turn(String words, int score) {
068    send("turn " + score + " " + words);
069  }
070  /** 客户退出或离开程序时发送quit消息 */
071  void quit() {
072    send("quit " + id);  // tell other player
073    out.println("quit"); // unhook
074  }
075  // 启动线程管理客户方面的网络
076  private Thread t;
077  void start() {
078    t = new Thread(this);
079    t.start();
080  }
081  // 这里显示的静态变量和静态块被用来初始化keys Hashtable, 这里使用这个
082  // 散列表在keystrings中的字符串和数组位置之间映射
083  private static final int ID = 1;
084  private static final int ADD = 2;
085  private static final int DELETE = 3;
086  private static final int MOVE = 4;
087  private static final int CHAT = 5;
088  private static final int QUIT = 6;
089  private static final int TURN = 7;
090  private static final int ACCEPT = 8;
091  private static final int CHALLENGE = 9;
092  private static Hashtable keys = new Hashtable();
093  private static String keystrings[] = {
094    "", "id", "add", "delete", "move", "chat",
095    "quit", "turn", "accept", "challenge"
096  };
097  static {
098    for (int i = 0; i < keystrings.length; i++)
099      keys.put(keystrings[i], new Integer(i));
100  }
101  private int lookup(String s) {
102    Integer i = (Integer) keys.get(s);
103    return i == null ? -1 : i.intValue();
104  }
105  /** 该函数是游戏连接服务器的主循环。它进入一个阻塞调用的readline(),
106   *  这个调用在服务器返回一行文字时返回一个字符串。它使用StringTokenizer
107   *  将一行文字拆成单词。switch语句基于输入行的第一个单词分配合适的代码。
108   **/
109  public void run() {
110    String s;
111    StringTokenizer st;
112    while ((s = readline()) != null) {
113      st = new StringTokenizer(s);
114      String keyword = st.nextToken();
115      switch (lookup(keyword)) {
116      default:
117        System.out.println("bogus keyword: " + keyword + "\r");
118        break;
119      case ID:
120        id = st.nextToken();
121        break;
122      case ADD: {
123          String id = st.nextToken();
124          String hostname = st.nextToken();
125          String name = st.nextToken(CRLF);
126          scrabblet.add(id, hostname, name);
127        }
128        break;
129      case DELETE:
130        scrabblet.delete(st.nextToken());
131        break;
132      case MOVE: {
133          String ch = st.nextToken();
134          int x = Integer.parseInt(st.nextToken());
135          int y = Integer.parseInt(st.nextToken());
136          scrabblet.move(ch, x, y);
137        }
138        break;
139      case CHAT: {
140          String from = st.nextToken();
141          scrabblet.chat(from, st.nextToken(CRLF));
142        }
143        break;
144      case QUIT: {
145          String from = st.nextToken();
146          scrabblet.quit(from);
147        }
148        break;
149      case TURN: {
150          int score = Integer.parseInt(st.nextToken());
151          scrabblet.turn(score, st.nextToken(CRLF));
152        }
153        break;
154      case ACCEPT: {
155          String from = st.nextToken();
156          int seed = Integer.parseInt(st.nextToken());
157          scrabblet.accept(from, seed);
158        }
159        break;
160      case CHALLENGE: {
161          String from = st.nextToken();
162          scrabblet.challenge(from);
163        }
164        break;
165      }
166    }
167  }
168}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Tiger系列二:Tiger语言新特性
java分页导航生成工具
hibernate测试1创建javabean
Hibernate Annotations 实战
一步一步学Repast 第二章(把界面显示出来)
【面试现场】如何编程解决华容道问题?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服