📄 309-311.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:Implementing a High Score Server on a Network</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, Macmillan Computer Publishing
<br>
<b>ISBN:</b> 1571690433<b> Pub Date:</b> 11/01/96</font>
</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=8//-->
<!--PAGES=309-311//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="306-309.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="311-314.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading48"></A><FONT COLOR="#000077">Coding the run() Method</FONT></H4>
<P>OK, now for the fun part. Here comes the run() method. The first part gets the time and then enters into the loop that should continue as long as we have a ServerSocket and a HighScoreList to deal with. Remember that the accept() method blocks until it receives a connection request. If any requests come in while we are running this loop, they are queued until we call the accept() method again. Queued requests are answered in the order received (just like when you’re on hold for customer service).
</P>
<!-- CODE //-->
<PRE>
public void run() {
lastChange = System.currentTimeMillis();
while(servSock != null && L != null ) {
Socket sock = null;
try {
sock = servSock.accept();
System.out.println("Got connection: "+2357);
} catch (Exception e) {
System.out.println("Conneciton request failed");
System.exit(1);
}
</PRE>
<!-- END CODE //-->
<P>The next bit should look familiar, since we are again trying to open input and output streams to deal with the socket, plus we declare some Strings to use later:
</P>
<!-- CODE SNIP //-->
<PRE>
try {
DataInputStream dis = new DataInputStream( new ⇐
BufferedInputStream(
sock.getInputStream()));
PrintStream ps = new PrintStream( new BufferedOutputStream(
sock.getOutputStream(), 1024), false);
String inputLine=null, outputLine = "\n";
</PRE>
<!-- END CODE SNIP //-->
<P>We put the entire section of code, including all of the work we do, in one big <I>try</I> block, because the exception we are most likely to get is that the client hung up too early, and we want to immediately recover from that and go back to waiting for a new connection.</P>
<P>The next block of code is the actual protocol implementation, which shouldn’t have anything new in it. Notice how it is the exact opposite of the protocol stuff on the client side:</P>
<!-- CODE //-->
<PRE>
String command = "blah";
while( command != null && !command.startsWith("bye") ) {
StringTokenizer st1 = null;
inputLine = dis.readLine().trim();
if(inputLine != null) {
System.out.println("Got: "+inputLine);
st1 = new StringTokenizer(inputLine, "::");
}
if(st1 != null && st1.hasMoreTokens()) {
command = st1.nextToken();
if (command.startsWith("request")) {
if (st1.hasMoreTokens() && Long.valueOf( ⇐
st1.nextToken()).longValue() < lastChange )
outputLine = L.toDataString();
else
outputLine = "none";
ps.println(outputLine);
ps.flush();
}
if(command.startsWith("update")) {
if (L.tryScore( st1.nextToken() ) != null)
lastChange = System.currentTimeMillis();
}
}
}
</PRE>
<!-- END CODE //-->
<P>You may recall all that time we spent at the beginning setting up a good foundation for the HSob and HighScoreList classes. This is where it <I>really</I> pays off. Believe it or not, we are <I>done</I> with this part of the server. All we have to do is tidy up:</P>
<!-- CODE SNIP //-->
<PRE>
ps.close();
dis.close();
sock.close();
} catch (Exception e);
}
}
</PRE>
<!-- END CODE SNIP //-->
<P>It is impossible to emphasize too often the importance of thinking out your program design ahead of time. Because we had a well-written HighScoreList class, the server-side coding was quick and painless.
</P>
<H4 ALIGN="LEFT"><A NAME="Heading49"></A><FONT COLOR="#000077">Trying Out the New Server</FONT></H4>
<P>Ready to try out this new, improved server? OK, here’s what you should change the main() method to:
</P>
<!-- CODE SNIP //-->
<PRE>
public static void main(String args[]) {
HighScoreList theList = null;
theList = new
HighScoreList(Integer.valueOf(args[0]).intValue(),"Bob&100|Eric&2000");
new ServerThread(theList).start();
System.out.println("Server tracking "+args[0]+" scores.");
}
</PRE>
<!-- END CODE SNIP //-->
<P>What’s that <I>args[0]</I> stuff? Well, arguments that are passed to Java applications are stored in that array called <I>args[]</I>. You type in each argument, separated by a space. The value at <I>index 0 (args[0])</I> is always the first argument passed to the program. In this case, it is an integer specifying how many scores we want the server to track. Now, compile this and run it using the <I>java</I> command, <I>java HighScoreServer 10</I>. Then, start up the Appletviewer with our client and have it clone itself a few times.</P>
<P>Be sure that you choose to Change Colors in order to see the updated score list, and add all the scores you want to whatever instance of the client you want—they should all update to the same list. Normal games will be doing things other than just displaying high scores, so odds are they will have to refresh periodically anyway. Our poor testApp doesn’t do anything, so it has to be manually refreshed when a new score comes in.</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="306-309.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="311-314.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
</BODY>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -