⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 728-732.html

📁 java game programming e-book
💻 HTML
字号:
<HTML>
<HEAD>
<META name=vsisbn content="1571690433"><META name=vstitle content="Black Art of Java Game Programming"><META name=vsauthor content="Joel Fan"><META name=vsimprint content="Sams"><META name=vspublisher content="Macmillan Computer Publishing"><META name=vspubdate content="11/01/96"><META name=vscategory content="Web and Software Development: Programming, Scripting, and Markup Languages: Java"><TITLE>Black Art of Java Game Programming:The Internet MahJong Server</TITLE>
<!-- HEADER --><STYLE type="text/css">  <!-- A:hover  { 	color : Red; } --></STYLE><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"><script><!--function displayWindow(url, width, height) {         var Win = window.open(url,"displayWindow",'width=' + width +',height=' + height + ',resizable=1,scrollbars=yes');	if (Win) {		Win.focus();	}}//--></script><SCRIPT><!--function popUp(url) {        var Win = window.open(url,"displayWindow",'width=400,height=300,resizable=1,scrollbars=yes');	if (Win) {		Win.focus();	}}//--></SCRIPT><script language="JavaScript1.2"><!--function checkForQuery(fm) {  /* get the query value */  var i = escape(fm.query.value);  if (i == "") {      alert('Please enter a search word or phrase');      return false;  }                  /* query is blank, dont run the .jsp file */  else return true;  /* execute the .jsp file */}//--></script></HEAD><BODY> 
<TABLE border=0 cellspacing=0 cellpadding=0>
<tr>
<td width=75 valign=top>
<img src="../1571690433.gif" width=60 height=73 alt="Black Art of Java Game Programming" border="1">
</td>
<td align="left">
    <font face="arial, helvetica" size="-1" color="#336633"><b>Black Art of Java Game Programming</b></font>
    <br>
    <font face="arial, helvetica" size="-1"><i>by Joel Fan</i>
    <br>
    Sams,&nbsp;Macmillan Computer Publishing
    <br>
    <b>ISBN:</b>&nbsp;1571690433<b>&nbsp;&nbsp;&nbsp;Pub Date:</b>&nbsp;11/01/96</font>&nbsp;&nbsp;
</td>
</tr>
</table>
<P>

<!--ISBN=1571690433//-->
<!--TITLE=Black Art of Java Game Programming//-->
<!--AUTHOR=Joel Fan//-->
<!--AUTHOR=Eric Ries//-->
<!--AUTHOR=Calin Tenitchi//-->
<!--PUBLISHER=Macmillan Computer Publishing//-->
<!--IMPRINT=Sams//-->
<!--CHAPTER=18//-->
<!--PAGES=728-732//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="724-728.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="732-735.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H3><A NAME="Heading14"></A><FONT COLOR="#000077">The Basic Server</FONT></H3>
<P>We are now ready to start writing the server, which is a Java application that runs forever. It&#146;s always a good idea to write a simple version first. In this case, it only handles login, logout, communications, and joining and leaving tables. The packets needed for this task are summarized in Table 18-1. Client-to-server packets start with &#147;CP&#148; and vice versa with &#147;SP&#148;.
</P>
<TABLE WIDTH="100%"><CAPTION ALIGN=LEFT><B>Table 18-1</B> A basic list of packets
<TR>
<TH COLSPAN="3"><HR>
<TR>
<TH WIDTH="40%" ALIGN="LEFT">Packet Type
<TH WIDTH="20%" ALIGN="LEFT" VALIGN="BOTTOM">Fields
<TH WIDTH="40%" ALIGN="LEFT" VALIGN="BOTTOM">Description
<TR>
<TH COLSPAN="3"><HR>
<TR>
<TD>CP_LOGIN
<TD>name
<TD>Log in to the server.
<TR>
<TD>CP_QUIT
<TD>
<TD>Quit from the server.
<TR>
<TD VALIGN="TOP">CP_MESSAGE
<TD VALIGN="TOP">type, text
<TD>Sends a message, type is to server, all, or table.
<TR>
<TD VALIGN="TOP">CP_TABLE_JOIN
<TD VALIGN="TOP">id
<TD>Join or leave (id = -1) table.
<TR>
<TD VALIGN="TOP">CP_TABLE_SERVE
<TD VALIGN="TOP">options
<TD>Serve a new table (options reserved).
<TR>
<TD>SP_YOU_ARE
<TD>id
<TD>Your ID.
<TR>
<TD>SP_LOGIN
<TD>result
<TD>Your login result.
<TR>
<TD VALIGN="TOP">SP_JOIN
<TD VALIGN="TOP">id, name
<TD>Play logged in under this name.
<TR>
<TD>SP_LEAVE
<TD>id
<TD>Player quit.
<TR>
<TD VALIGN="TOP">SP_MESSAGE
<TD VALIGN="TOP">type, id, text
<TD>Player sends message, type is from server, all, or table.
<TR>
<TD VALIGN="TOP">SP_TABLE_OPT
<TD VALIGN="TOP">t, options
<TD>This table is open (options reserved).
<TR>
<TD VALIGN="TOP">SP_TABLE_PLAYER
<TD VALIGN="TOP">t, s, id
<TD>Player on this table in this seat, id = -1 means left table.
<TR>
<TD COLSPAN="3"><HR>
</TABLE>
<H4 ALIGN="LEFT"><A NAME="Heading15"></A><FONT COLOR="#000077">The Server Class</FONT></H4>
<P>The server class contains the main() method. Its job is to do some initialization, create a ServerSocket, and accept connections.
</P>
<!-- CODE //-->
<PRE>
package server;
import java.net.*;
import java.io.*;

class FullServerException extends Exception;
class Server &#123;
  public static void main (String args[]) &#123;
    ServerSocket main_sock = null;
    try &#123;
      main_sock = new ServerSocket(5656);  // default port
    &#125; catch (IOException e) &#123;
      System.out.println;
      System.exit(1);
    &#125;
    while (true) &#123;
      try &#123;
        Socket s = main_sock.accept();     // accept connection
        DataInputStream i = new DataInputStream(s.getInputStream());
        DataOutputStream o = new DataOutputStream(s.getOutputStream());
        (new Player(s, i, o)).start();     // start thread
      &#125; catch (Exception e) &#123;
        System.out.println;
      &#125;
    &#125;
  &#125;
&#125;
</PRE>
<!-- END CODE //-->
<H4 ALIGN="LEFT"><A NAME="Heading16"></A><FONT COLOR="#000077">The Player and PlayerOutput Classes</FONT></H4>
<P>We first group some information about a player into the Player class:
</P>
<!-- CODE //-->
<PRE>
package server;
import java.net.*;
import java.io.*;
class Player extends Thread &#123;
  public static Player[] global = new Player[100];
  public int id = -1;
  public String name = null;
  private Socket sock;
  private DataInputStream in;
  private DataOutputStream out;
  public boolean connected = true;
  private PlayerOutput out_thread = null;
  public Table table = null;
  public int seat = -1;
&#125;
</PRE>
<!-- END CODE //-->
<P>The above definition includes the player&#146;s name, his socket connection, table and seat, and so on. There is a static array <I>global</I> that holds all the players on the server. Each player has a unique ID, which is an index into this array. To construct a new Player instance, we need to find an empty slot. Here it is important to use the <I>synchronized</I> statement on the array <I>global</I>, because our server will be a multithreaded program, and other threads may want to modify <I>global</I>, too. In case the server is full, we throw a FullServerException to inform our caller, Server.main().</P>
<!-- CODE //-->
<PRE>
public Player (Socket s, DataInputStream in, DataOutputStream out)
throws FullServerException &#123;
  synchronized (global) &#123;          // find a unique player id
    for (int i = 0; i &lt; global.length; i&#43;&#43;) &#123;
      if (global[i] == null) &#123;
        id = i;
        global[i] = this;
        break;
      &#125;
    &#125;
  &#125;
  if (id == -1)                    // all slots full
    throw new FullServerException();
  sock = s;
  this.in = in;
  this.out = out;
  (out_thread = new PlayerOutput(this, out)).start();
  output(Packet.SPYouAre(id));     // notify the player
&#125;
</PRE>
<!-- END CODE //-->
<P>We need methods to send out packets. Player.output() sends a packet to a player. I will explain it in more detail soon. The static method outputAll() sends a packet to everyone on the server. It works by first acquiring the monitor associated with <I>global</I> and then calling every player&#146;s output() method. We also need a disconnect() method, called when a player decides to quit (his client sends the server a CP_QUIT packet for this purpose) or when his network connection is somehow dead.</P>
<!-- CODE //-->
<PRE>
public void output (byte[] p) &#123;
  if (connected)
    out_thread.output(p);
&#125;
public static void outputAll (byte[] p) &#123;
  synchronized (global) &#123;       // critical section
    for (int i = 0; i &lt; global.length;  i&#43;&#43;) &#123;
      Player him = global[i];
      // only send to players who have logged in
      if (him != null &#38;&#38; him.name != null)
        him.output(p);
    &#125;
  &#125;
&#125;
public synchronized void disconnect () &#123;
  if (id == -1) return;         // we do it only once
    connected = false;
    if (table != null)            // leave the table
      table.leave(this);
    synchronized (global) &#123;       // critical section
      global[id] = null;          // will GC eventually
    &#125;
    try &#123;                         // close the socket
      in.close();
      out.close();
      sock.close();
    &#125; catch (IOException e) &#123;
    &#125;    if (name != null)             // announce leave
      outputAll(Packet.SPLeave(id));
    id = -1;                      // we're done here
  &#125;
// ...
&#125;
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="724-728.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="732-735.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>


</BODY>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -