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

📄 tij0167.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<html><body>

<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0166.html">Prev</a> | <a href="tij0168.html">Next</a>
</td>
</tr></table>
<hr>

<H2 ALIGN=LEFT>
A
Web application
<P><A NAME="Index2691"></A><A NAME="Index2692"></A></H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
let&#8217;s consider creating an application to run on the Web, which will show
Java in all its glory. Part of this application will be a Java program running
on the Web server, and the other part will be an <A NAME="Index2693"></A><A NAME="Index2694"></A>applet
that&#8217;s downloaded to the browser. The applet collects information from
the user and sends it back to the application running on the Web server. The
task of the program will be simple: the applet will ask for the email address
of the user, and after verifying that this address is reasonably legitimate (it
doesn&#8217;t contain spaces, and it does contain an &#8216;@&#8217; symbol)
the applet will send the email address to the Web server. The application
running on the server will capture the data and check a data file in which all
of the email addresses are kept. If that address is already in the file, it
will send back a message to that effect, which is displayed by the applet. If
the address isn&#8217;t in the file, it is placed in the list and the applet is
informed that the address was added successfully.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Traditionally,
the way to handle such a problem is to create an <A NAME="Index2695"></A><A NAME="Index2696"></A>HTML
page with a text field and a &#8220;submit&#8221; button. The user can type
whatever he or she wants into the text field, and it will be submitted to the
server without question. As it submits the data, the Web page also tells the
server what to do with the data by mentioning the <A NAME="Index2697"></A><A NAME="Index2698"></A><A NAME="Index2699"></A>Common
Gateway Interface (CGI) program that the server should run after receiving this
data. This CGI program is typically written in either Perl or C (and sometimes
C++, if the server supports it), and it must handle everything. First it looks
at the data and decides whether it&#8217;s in the correct format. If not, the
CGI program must create an HTML page to describe the problem; this page is
handed to the server, which sends it back to the user. The user must then back
up a page and try again. If the data is correct, the CGI program opens the data
file and either adds the email address to the file or discovers that the
address is already in the file. In both cases it must format an appropriate
HTML page for the server to return to the user.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">As
Java programmers, this seems like an awkward way for us to solve the problem,
and naturally, we&#8217;d like to do the whole thing in Java. First,
we&#8217;ll use a Java applet to take care of data validation at the client
site, without all that tedious Web traffic and page formatting. Then
let&#8217;s skip the Perl CGI script in favor of a Java application running on
the server. In fact, let&#8217;s skip the Web server altogether and simply make
our own network connection from the applet to the Java application on the server!
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">As
you&#8217;ll see, there are a number of issues that make this a more
complicated problem than it seems. It would be ideal to write the applet using
Java 1.1<A NAME="Index2700"></A>
but that&#8217;s hardly practical. At this writing, the number of users running
Java 1.1-enabled browsers is small, and although such browsers are now commonly
available, you&#8217;ll probably need to take into account that a significant
number of users will be slow to upgrade. So to be on the safe side, the applet
will be programmed using only Java 1.0<A NAME="Index2701"></A>
code. With this in mind, there will be no JAR files to combine 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>.class</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
files in the applet, so the applet should be designed to create as few 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>.class</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
files as possible to minimize download time.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Well,
it turns out the Web server (the one available to me when I wrote the example) 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>does</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
have Java in it, but only Java 1.0<A NAME="Index2702"></A>!
So the server application must also be written using Java 1.0.
</FONT><a name="_Toc408018773"></a><P></DIV>
<A NAME="Heading521"></A><H3 ALIGN=LEFT>
The
server application
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
consider the server application, which will be called 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>NameCollector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
What happens if more than one user at a time tries to submit their email
addresses? If 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>NameCollector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
uses TCP/IP sockets, then it must use the multithreading approach shown earlier
to handle more than one client at a time. But all of these threads will try to
write to a single file where all the email addresses will be kept. This would
require a locking mechanism to make sure that more than one thread
doesn&#8217;t access the file at once. A semaphore will do the trick, but
perhaps there&#8217;s a simpler way. 
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
we use datagrams instead, multithreading is unnecessary. A single <A NAME="Index2703"></A><A NAME="Index2704"></A>datagram
socket will listen for incoming datagrams, and when one appears the program
will process the message and send the reply as a datagram back to whomever sent
the request. If the datagram gets lost, then the user will notice that no reply
comes and can then re-submit the request.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
the server application receives a datagram and unpacks it, it must extract the
email address and check the file to see if that address is there already (and
if it isn&#8217;t, add it). And now we run into another problem. It turns out
that Java 1.0 doesn&#8217;t quite have the horsepower to easily manipulate the
file containing the email addresses (Java 1.1<A NAME="Index2705"></A>
does). However, the problem can be solved in C quite readily, and this will
provide an excuse to show you the easiest way to <A NAME="Index2706"></A><A NAME="Index2707"></A><A NAME="Index2708"></A><A NAME="Index2709"></A>connect
a non-Java program to a Java program. A <A NAME="Index2710"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Runtime</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object for a program has a method called <A NAME="Index2711"></A><A NAME="Index2712"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>exec(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that will start up a separate program on the machine and return a <A NAME="Index2713"></A><A NAME="Index2714"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Process</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object. You can get an <A NAME="Index2715"></A><A NAME="Index2716"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>OutputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that connects to standard input for this separate program and an <A NAME="Index2717"></A><A NAME="Index2718"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>InputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that connects to standard output. All you need to do is write a program using
any language that takes its input from standard input and writes the output to
standard output. This is a convenient trick when you run into a problem that
can&#8217;t be solved easily or quickly enough in Java (or when you have legacy
code you don&#8217;t want to rewrite). You can also use Java&#8217;s 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>native
methods
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(see Appendix A) but those are much more involved.
</FONT><P></DIV>
<A NAME="Heading522"></A><H4 ALIGN=LEFT>
The
C program
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
job of this non-Java application (written in C because Java wasn&#8217;t
appropriate for CGI programming; if nothing else, the startup time is
prohibitive) is to manage the list of email addresses. Standard input will
accept an email address and the program will look up the name in the list to
see if it&#8217;s already there. If not, it will add it and report success, but
if the name is already there then it will report that. Don&#8217;t worry if you
don&#8217;t completely understand what the following code means; it&#8217;s
just one example of how you can write a program in another language and use it
from Java. The particular programming language doesn&#8217;t really matter as
long as it can read from standard input and write to standard output.
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Listmgr.c</font>
<font color="#009900">// Used by NameCollector.java to manage </font>
<font color="#009900">// the email list file on the server</font>
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#define BSIZE 250

<font color="#0000ff">int</font> alreadyInList(FILE* list, <font color="#0000ff">char</font>* name) {
  <font color="#0000ff">char</font> lbuf[BSIZE];
  <font color="#009900">// Go to the beginning of the list:</font>
  fseek(list, 0, SEEK_SET);
  <font color="#009900">// Read each line in the list:</font>
  <font color="#0000ff">while</font>(fgets(lbuf, BSIZE, list)) {
    <font color="#009900">// Strip off the newline:</font>
    <font color="#0000ff">char</font> * newline = strchr(lbuf, '\n');
    <font color="#0000ff">if</font>(newline != 0) 
      *newline = '\0';
    <font color="#0000ff">if</font>(strcmp(lbuf, name) == 0)
      <font color="#0000ff">return</font> 1;
  }
  <font color="#0000ff">return</font> 0;
}

<font color="#0000ff">int</font> main() {
  <font color="#0000ff">char</font> buf[BSIZE];
  FILE* list = fopen("emlist.txt", "a+t");
  <font color="#0000ff">if</font>(list == 0) {
    perror("could not open emlist.txt");
    exit(1);
  }
  <font color="#0000ff">while</font>(1) {
    gets(buf); <font color="#009900">/* From stdin */</font>
    <font color="#0000ff">if</font>(alreadyInList(list, buf)) {
      printf("Already in list: %s", buf);
      fflush(stdout);
    }
    <font color="#0000ff">else</font> {
      fseek(list, 0, SEEK_END);
      fprintf(list, "%s\n", buf);
      fflush(list);
      printf("%s added to list", buf);
      fflush(stdout);
    }
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
assumes that the C compiler accepts 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>&#8216;//&#8217;</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
style comments. (Many do, and you can also compile this program with a C++
compiler.) If yours doesn&#8217;t, simply delete those comments.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
first function in the file checks to see whether the name you hand it as a
second argument (a pointer to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>char</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">is
in the file. Here, the file is passed as a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>FILE</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
pointer to an already-opened file (the file is opened inside 

⌨️ 快捷键说明

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