Wednesday, May 04, 2011

20 HTML Tags to do Almost Everything You Need a Web Page to do

Ah HTML. The gateway to programming, or at least mine. After the time I've spent as a developer, the importance of understanding how to put together some solid HTML has not waned. So, I thought it would be a good idea to distill the fundamentals down to a concise reference.

What's great is that there's only about twenty tags that you'll need to do all the basic important things in order to structure data. This is how it's going to go. You'll need to know what HTML is supposed to do first. Basic, but important. Then, you'll need to learn a couple simple rules to help categorize the types of tags you'll need. Finally, we'll put it all together so you can learn about how specific tags work.

What is HTML for?

Quite simply, HTML helps to describe your textual content. It stands for HyperText Markup Language. The markup part is what adds meaning to the content. Need an example? Let's say that I want to emphasize to a word in a sentence. To do that with plain text isn't possible without adding some extra information. When we speak, we can use inflection in our voice, but with a plain sentence, you can't do much. See the need? In order to do this, you can wrap content in HTML tags.

Here's a sentence that has some emphasis.
Here's a sentence that has <em>some</em> emphasis.

The "<em>... </em>" is an HTML tag that describes the text that it surrounds, emphasizing it.


Let's start with an example, based on the example above. Here is our HTML

<p>Here's a sentence that has <em>some</em> emphasis.<br />This one appears on a new line.</p>

  1. Tags use angle brackets (less than, greater than characters) to distinguish themselves from the actual content. The example above starts with a <p> tag. The characters in between the angle brackets, in this case the "p" in the "<p>" indicates a tag with a specific purpose. The <p> indicates a paragraph, hence the "p".
  2. Tags have a start and a matching end. We call that "opening" and "closing." The main difference is that the closing tag has a forward slash, an opening tag does not. If a browser is reading the HTML you write from start to finish, when it reads "<p>" it says to itself "everything after this tag, until I reach the closing tag, is part of a paragraph". When it reaches the matching "</p>" it says to itself "I can stop rendering the paragraph now."

    Can you spot another opening and closing tag in our example? I thought so. "<em>some</em>" formats the word "some" with the "emphasize" tag.
  3. Some tags can be empty, where there is no content in between an opening and closing tag. There, a single tag can open and close itself. The syntax places the forward slash at the tail end of the tag. Our example above has a "<br />" tag, indicating a line break. These kinds of tags are "self-closing" or simply "empty" tags because they do not wrap content.
  4. Tags must be symmetric. This one is easiest to show with an example. This is not symmetric.

    <p>New paragraph <em>emphasized</p></em>

    In this example, you can see that the <p> opens, then an <em> tag opens. The </p> then closes before the </em> closes. Don't do this! This is how it should look

    <p>New paragraph <em>emphasized</em></p>
  5. Tags can be nested. That is, you can put tagged content inside other tags. In the example above, the <em> tag is nested in the <p> tag. This helps to build a hierarchy of structured content. Just remember to make sure that the the tags need to be symmetric.

    It is also important to note that all tags have their own set of rules. Some tags can have only specific types of tags nested within. Depending on the tag, some tags might be forbidden.
  6. There is a distinction between "block level" and "inline" tags. This is an important concept to understand which describes how the tag behaves on the page. You can think of a block level tag as behaving like a rectangular container. Inline tags wrap with the text that they contain.
  7. Tags can have attributes. These provide ways to configure the tag. An attribute of an HTML tag is simply a pair of a name and value. This is what a paragraph tag looks like with an "id".

    <p id="Something">The ID is Something</p>
Twenty tags you'll find most useful.

Now that you know a few rules, it's time to get into some specifics. Here is a list of 20 tags that will help you to build your very own HTML page. The intention here is to briefly describe the rules for how these tags behave so you have enough freedom to build your own HTML content.

The first set of tags help to set up the entire document structure.

1. <html>... </html>

If you're building a complete HTML file, it must open and close with this one. This is the root tag that you'll need to use.

This only appears at the root of the file. That is to say, there are no HTML tags that can wrap this one, and it can contain ONLY <head> and <body> tags, in that order.

2. <head>... </head>

The head tag sits as the first element in the HTML page. The contents describes the file, but does not contain content. THis is where you add the title, add style, javascript, and meta information.

This Must be the first tag to appear within the <html> tag. It does not contain any actual page content.

3. <title>... </title>

The title tag is what's used to give the page a title. This is what appears in the top bar of the browser window.
This appears only within the <head> tag and only contains text, no other tags.

4. <body>... </body>

The body tag is where the actual content appears.

This appears after the <head>... </head> tag and contains any content-bearing tags

Here's an example, with the basics of what we've learned so far

<title>My First HTML</title>
<body>This is the page content</body>

Not too hard, eh? Everything else helps to describe the actual content that falls inside the <body> tag.

5. <h1>...</h1> through <h6>...</h6>

These are headings. These help to indicate the title of content that follows, like a headline for a newspaper article. Search engines have traditionally placed greater emphasis to text within these tags. This makes sense semantically, because if there is a heading on the page, this is likely to indicate something significant that appears within. These help to identify what the content on the page is about. <h1> identifies the most important heading and <h6> the least. You can have as many of these as you like on the page.

This is a block level element. You can put a lot of different elements within it, including inline elements, images, line breaks. Other block level elements should stay out.

6. <p>

The paragraph tag is the main tag to use for blocks of text content. Similar to the headings, you can put inline elements, images, and line breaks within.

7. <a>

Ahh the anchor tag. This is what the world wide web was built on. The anchor tag allows you to link to another web page or other url's. To make it work, just add an "href" attribute.

<a href="">THis is a link</a>
  • The value of the href attribute is the place where the link should take you.
  • This is an inline element
  • You can put other inline elements inside the anchor tag.

8. <img />

The image tag let's you put an image on the page. This is another tag that requires an attribute to work. You need to use the "src" attribute to specify the address of the image. You can also use the "width" and "height" attributes if you need to control the size. If you specify only one of them, the unspecified dimension will scale proportionately. The value of the "height" and "width" attributes is measured in pixels

<img src="" width="100" height="200"/>

This is an inline element and an empty tag.

9. <br />

This is a line break. Quite simply, it places a break in t a line so the text following it appears on a new line.


Lists are a very important way to present text on a web page. With the nature of short attention spans abounding on the internet, there's nothing like a list to make content easy to digest. In addition, they help tremendously when you need to display information in a hierarchical way.

10. <ul>

This is an Unordered List, or as we typically know it, a bulleted list. This is a block level element in which List Items are placed. The only tag that you can legally put into a <ul> tag is a <li> tag. This is what a bulleted list might look like


This is what it looks like
  • Fruits
  • Vegetables
  • Proteins
What's cool about lists is that they can be nested inside each other. A <ul> tag can rest within a <li> tag, which builds a hierarchy, like this.

This is what it looks like
  • Fruits
    • Apples
    • Oranges
    • Lemons
  • Vegetables
    • Carrots
    • Broccoli
    • Beets
  • Proteins
    • Beef
    • Salmon
    • Chicken

11. <ol>

The more organized sibling to the Unordered List, is the Ordered List. It works the same way as the unordered list does, but it appears on the page with numbers instead of bullets. You can nest these within each other as well. You can even mix an ordered list with an unordered list. Check this out.

<li>Top Fruits
<li>Top Vegetables
<li>Top Proteins

This is what it looks like
  • Top Fruits
    1. Apples
    2. Oranges
    3. Lemons
  • Top Vegetables
    1. Carrots
    2. Broccoli
    3. Beets
  • Top Proteins
    1. Beef
    2. Salmon
    3. Chicken

12. <li>

The List Item is an HTML tag that belongs only in a <ul> or <ol> tag. Any place else is just wrong. The content of <li> tag is a little more flexible. They are block level elements, so you can put other block level elements in them -- headings, paragraphs, other lists, and such. You can of course put inline elements in these as well -- anchors, images, plain text, whatever.


Sometimes, you'll find it necessary and important to add some visual formatting to your text. Most of the time, it's best to use Cascading Style Sheets (CSS) to do that (which I don't cover at ALL here). However, it is still legal to add some text formatting with HTML tags. Here's 2 common ones

13. <strong> or <b>

Wrapping text in the Strong or Bold tag has the same default effect. This makes the text inside it bold. The main difference is that the <strong> tag is interpreted by screen readers (web browsers for the vision-impaired) in such a way as to raise a voice.

These tags are inline elements, and should only contain other inline elements.

14. <em> <i>

The Emphasis and Italic tags also have the same default effect. These make the text inside italic. The <em> tag has the same analogous interpretation as the <strong> tag by screen readers. It adds some, eh, emphasis to the text.

These tags are inline elements as well, and should only contain other inline elements. Here's an example of something that is both bold and italic

<strong><i>Bold and Italic</i></strong>


The table is one of the most powerful layout elements that HTML provides. This allows you to place content into a grid of columns and rows. To use a table, there are three main pieces involved. A tabular layout will consist of the table container, rows within that container, and cells within each row. The cells are the only thing in the table that can contain any actual content of the table.

15. <table>

The Table tag is the tag that starts the table. Alone, it doesn't do much. In fact, it is not valid to have <table> tag with nothing in it. It simply doesn't make sense to set this up without contents inside. There are only a couple of valid tags that can be direct children of a <table> tag, and they are all specific to a tabular layout.

16. <tr>

One of the main HTML tags that can be a child of a <table> tag is the Table Row. This too requires content to be valid. The content of a table row can only be one of two table cell tags. Those follow

17. <td>

The Table Data cell can only appear within a <tr> tag. However, the <td> tag can contain just about anything it wants to. Other tables, headings, images, plain text, paragraphs -- just about anything that doesn't have any limitations on what it's parent tag is can go in here. Here is a sample table with one row, and two columns:


This is what it looks like with a border

One Two

18. <th>

Another tag that can appear within the <tr> tag is the Table Heading tag. The <th> helps to declare what the heading of a table is. Typically, this tag will appear in the top row of a table to indicate the name of the column. However, there are no restrictions on which position they reside in a <tr>. Other than the semantic nuance, a <th> behaves the same way as the <td> tag does.


This is what it looks like with a border

Letters Numbers
A 1
B 2
C 3

Document Structure

Occasionally, it's nice to have a tag just to collect a group of content together, simply for the purpose of putting a boundary around it. For that purpose, and it is a common one, we have a couple tags to help.

19. <div>

The Division tag , frequently referred to simply as a "div", defines a section of the page. That's it. It does not have any significant impact on the display of it's contents other than acting as a block level type of container for it's contents.

The simplicity of a <div> provides a lot of flexibility in structuring the content of an HTML file. As you work on building HTML over time, you'll find yourself using this a lot. Especially when there are a lot of different blocks of content that you want to group together visually.

The contents of a <div> are very flexible. Any tag that doesn't have any restrictions on what it's parent tag can be are allowed here. Tables, other divs, inline elements, etc. The <div> tag is a block level element.

<h1>Here's a heading</h1>
<p>Here's a paragraph grouped with the heading</p>

20. <span>

The Span tag similarly wraps content for the sake of grouping content together. The main difference between the <div> tag and the <span> tag is that the span tag is an inline element. That means that it can only contain raw text or other inline elements.

Here's an example that shows nested span tags to group some words together.

<span>Here is some text <span>and this is a sub-group of text</span></span>


What you see above represent what I consider the essentials to building an HTML document. Much of the other parts of HTML (and there are many) are more specialized. For example, we didn't touch form elements or some more advanced table features. However, what's above will give you what you need to get started.

There are a couple items that are worth noting, as a bonus.

21. <!DOCTYPE >

The first bonus is the Document Type declaration. This is a line that goes at the very top of the page to help the browser determine what how to read the rest of the HTML that you wrote. Believe it or not, there are a couple different flavors of HTML, and each has slightly different rules. The Document Type helps to tell the browser what rules your HTML adheres to. Using a document type is not a requirement, but it is a very good idea. People who write good HTML code use doctypes.

The doctype for HTML that uses the HTML5 rules is refreshingly simple:

The doctype for HTML that uses the XHTML Strict rules is a little more verbose. I don't know anyone who has it memorized:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">

An HTML document with a proper HTML5 document type declaration would look like this
<head><title>HTML 5 page</title></head>
<body>This is an HTML 5 page</body>

22. <!-- Comments -->

Last but not least, the comment is something you should be aware of. The comment tag allows you to add comments to the code you're writing, which the browser will not show. They can be helpful in making notes to help you understand the HTML you write. This is what a comment inside a Paragraph would look like.

<p>I love to write HTML <!-- as long as someone is paying for it --></p>

In that example, the only thing that the end user would see is the "I love to write HTML". Everything inside the <!-- ... --> does not show. As you can see, it is a helpful way to communicate between people writing the code.

So that's it! You should be off to the races now. Be careful though. Once you get started with this, it's hard to stop. And once you get into using javascript to add interactive behavior, and CSS to control your visual style, it's nearly impossible.

Tuesday, October 20, 2009

Upgrade to Snow Leopard Freezes at Boot -- FIXED!

A couple of weeks ago, I decided that I'd do a standard upgrade to Mac OS X Snow Leopard. I was wary because I have a fairly customized installation of Leopard. I've done a good deal of tweaking in the Terminal to get things set up for the sake of web development. However, having faith, I went ahead and did it any way. I figured that it would go smoothly.

It did not.

Right away when booting in to my account the system would hang. I'd get the spinning beach ball, and the magnifying glass for Spotlight appearing in the top right corner. Nothing else. No dock. No menu bar. Nothing. Frozen. I could safe boot in to the system with my account (holding down shift button when starting) but a standard log in would not work.

At that point, I decided that I'd revert with a complete time machine backup and try again some other day. I shifted my strategy to do a clean install.

A week later, my adventure with a clean install began. Until last night, I was quite pleased with the progress. Happy with the installation and configuration of the system, I started transferring files. Then I started with the fonts. I copied the contents of the ~/Library/Fonts directory from the leopard disk to my clean snow leopard disk. It took a lot longer than it should have. I copied the contents of the ~/Library/FontCollections directory in the same way. I was immediately suspicious. I then un-did those copies. Removed all of the user fonts. Removed the new Font collections. Something just didn't seem right. Curious but content, I moved on.

I then started up an instance of Eclipse. And it crashed. I checked the log, where I saw a NullPointerException which mentioned this:
Very interesting.

I then rebooted the machine, and found the same problem that I had when I did the normal upgrade. System hang. Frozen. The spinning beach ball of death. Defeated, I went to bed.

Thinking that the problems I had were probably related, I did a search to see if clearing the font caches might work. Honestly, I didn't even know if there was such a thing. Apparently there is, and this is where I found the details about clearing a font cache in Mac OS X.

The good news is that clearing the font cache worked! I've managed to fix the problem and boot in to Snow Leopard without hanging or freezing. This is what I did:

  1. Consider removing all of your user fonts and font collections -- I don't know if this is necessary.
  2. Reboot, holding down the SHIFT button as the system starts - this boots into safe mode
  3. Log in to your account from the log in screen
  4. Open the Terminal (Applications/Utilities/Terminal)
  5. At the command line, use aprutil to clear the font cache type this:
    atsutil databases -removeUser

    If you want to remove font caches for all users (I did), type this:
    sudo atsutil databases -remove

    Since you're using sudo to execute this command, you will need an administrator password.
  6. Reboot the machine, and you should be good to go. At least, if you have the same problem I did.

Monday, December 29, 2008

Gratuitous family media

I feel that I'm just not doing a good job as a Dad unless I blog about my kids now and then. For those far flung, here's a set of recents.

It's impossible to resist giggling along with this one of Nolan laughing hysterically at the frog blowing in his face


And representing for the Badgers in the apron Grandma sent, here's Gideon drawing with his markers.


A few family shots.

My favorite people in the world.

Gideon demonstrating the laws of physics.

Nolan, grinning as always.

Yours truly making sushi. We found a good deal on some yellow fin, but had to make due with sub standard, non-sushi rice -- which explains the look on my face.

One of Gideon's favorite video games is "Photoshop." He picks out the colors and the brush. Then I hold down the mouse button of a laptop while he moves his finger around on the track pad to do the drawing. Tons of fun!

Tuesday, December 16, 2008

Bailout your bicycle

If there's a silver lining to the $700 billion bailout it's legislation about giving bicyclists a tax break.

As a year round commuter facing sub-zero temps and snow this week, I was excited to see this news. Really, $20 / month doesn't cover a whole lot in bicycle expenses, but hey, I still think it's great news.

Tuesday, September 02, 2008

Prophecy? Europe?

Oh yes, Europe and prophecy go together more than you might think.

This Sunday, September 7th, 2008, if you happen to be within ear-shot of Fort Collins, you should consider checking out a lecture about the role of Europe in light of Biblical prophecy. Norbert Link will be presenting a message that I think is significant in the scope of world history. I'm not even exaggerating.

By connecting the evidence of current events and secular history with prophecy, the news reported today from around the world becomes absolutely magnified in significance. I don't know all of the details about the content of the lecture, but I do know that you can expect to hear about the prophetic emergence of the European Union to global power. Right now, the EU is in its infancy and might not seem like a global super power, but I believe it will be. Power has already begun to shift in significant ways. Merely seeing that the Euro is gaining greater influence as the currency of choice in international trade, because of the instability of the dollar, with increasing momentum is an indication of the power shift. I'm not an expert economist, nor am I informed of all the intricacies of global politics, but it doesn't take much to notice that the EU is gaining influence quickly. As the EU becomes more organized and better at making decisions, they will become more powerful. And, by joining so many disparate peoples and populations, the European Union will become the statue with feet of iron and clay mentioned in Daniel 2. At least, that's what I believe the Bible teaches.

You'll also likely hear something interesting about the removal of blessings from the United States and United Kingdom. Essentially, the premise is that these countries are the inheritors of the birthright from Jacob in Genesis 48, becoming a "great people" and "multitude of nations" respectively. Of course, since it is a lecture about the teachings of the Bible, you may hear about the many reasons why these birthright blessings are being withdrawn as well.

Ultimately, the shift in global power we're seeing right now is all part of the plan that the Bible records. And that's a good thing. However, what's shocking is that it doesn't take much imagination fill in the gaps between current events and Revelation events.

What you won't hear will be requests for money, a devotional altar call, nor a feel-good "just love the Lord" message. It will be a much more sobering set of content. What you will hear, even if you don't agree with it all, is an observation and analysis of current events and history that will blow your mind, if you take the Bible seriously.

I challenge you to open your mind and check it out.

Tuesday, June 10, 2008

...and Baby Makes Four

About three weeks ago my wife, Shana and I arrived home carrying our newborn baby boy Nolan from the hospital. This is certainly a long overdue post, but bringing a newborn into the household tends to force some re-prioritization. Blogging fell pretty far down the list. So, without further adieu, a photo or 2. Introducing, Nolan.

I also figured that this would be a good place to record some of the details. At least before I forget them.

Over the weekend of May 17-18th, Shana noticed some different activity going on in her body. She had plenty of Braxton-Hicks contractions throughout the pregnancy, and what she was feeling was definitely more serious. So, I managed to scramble getting some things together Friday night, expecting that we might have to make a quick getaway. That was not the case. Things settled down completely. But we were warned.

Monday (May 19th) morning we woke up, and almost immediately became aware that we were going to be parents to a new child that day. The real contractions were regular and definitely stopped Shana in her tracks once in a while. To make things more interesting, I had an appointment with a recruiter that morning to talk about my job search -- I had actively started looking for a new job a week earlier and needed to find something fast. With things relatively stable at home, I figured that I'd take a calculated risk and go to the meeting. While Shana was at home, in labor, I was sitting at a coffee shop waiting very impatiently for the recruiter to show up. After ten looooooong minutes, and no show by the recruiter (communication mix up) I decided to leave. I'm glad I did.

I got home around 10:30 am and called up Shana's brother, Robb, to arrange a pickup for our two year old, Gideon. He stopped by around 11 am and picked him up, to deliver to Granny and Papa. Everything was pretty well under control at that point.

Contractions were still relatively mild, so in order to encourage them along, we decided to go for a walk around the neighborhood. It certainly worked. When we arrived back home an hour later, Shana was having contractions anywhere from 5 to 6 minutes apart. Right on track.

Our plan was to allow Shana to labor as much as possible in the comfort of our home before arriving at the hospital for the delivery. We had been through it once before, taking Bradley method classes, so we had a pretty good idea of what to do. Shana immediately laid down to get some much needed rest while the contractions did their work. I think she may have even gotten a little bit of sleep.

While she was resting and allowing labor to naturally progress, I was tediously filling out a job application, hunting down history and contact information. I had a potential job offer in the works, and didn't want to take too long to respond. I'm sure they would have been understanding about any delays, but to me it was baggage that I could clear from my head. It also gave me something to do as an outlet for all the nervous energy. So, I did as much as I could, and kept as much job seeking momentum as I could.

Around 3 pm, while I was doing some scanning, Shana mentioned, in a tone that could not be ignored, that she was going to need some attention soon. Scanning could wait.

From that point on, things happened pretty rapidly. She was struggling to find the most comfortable position to be in while the contractions strengthened. Hands and knees? Nope. Sitting on a therapy ball at the end of the bed? Nope. Kneeling on the floor, resting on the bed? Nope. The most comfortable position wound up being a side-lying position on the bed. Good enough for me. I tended to her, trying to massage as much as I could to relieve the pressure. I then called the midwives to let them know that we were in active labor and that they could expect to see us later that day.

Continuing to labor, more intense, deep moaning turns out to be unbelievably helpful for Shana. In the back of my head, I was thinking to myself that the first time we had a baby, the moaning was quickly followed with pushing -- hmmmm. Time to pay close attention. Shana, to her credit, was extremely well composed, especially in retrospect. She looked relaxed, and there was no screaming in pain, but she was definitely working pretty hard. Cool towels were what she needed most. At that point, contractions were anywhere from 5 minutes to 3 minutes apart.

4:00 pm. Shana and I decide that it's time to start moving to the car to get to the hospital for the delivery. I call the midwives to let them know we're on our way. While I'm on the phone, Shana cries out, "I feel like pushing!!!" I really didn't want to hear that. Both of us panic slightly because we KNOW that we stayed home too long. I call the midwives back. "Shana feels like pushing, we're going NOW!"

Then began our lengthy venture down the stairs. Wow, it took some time. Trying to convince a laboring woman, who feels like pushing that she needs to start moving down stairs is like, well, just what it sounds like. It took 30 minutes to get downstairs. And, about half way down, her water broke.


Her pitch rises in fear. In a moment of idiotic diplomacy, I ask her if she wants to ride in the car, or if I should call an ambulance. I definitely didn't need to burden her with something as serious as a decision. Anyway, while I scramble to grab all of our bags in my arm, she found enough strength to make it half way across the front yard before another contraction hits. Remember, she feels like pushing. I hold her up to support and notice that she's crossing her legs at the knee. I nearly freak out. OK, that one's over, let's get her in the car.

She manages to get into the car, but there's absolutely no way she's going to actually sit. She knelt on the front seat, butt towards the windshield, hugging the headrest, while I drove as swiftly as possible to the hospital.

12 minutes later, Shana hasn't given birth yet, and we arrive at the hospital emergency room meeting our midwife at the entrance. They get a gurney, and try to decide whether to deliver the baby in the emergency room or in the actual birthing room. Shana decides that she can make it to the birthing room. Good thing too. I don't get the impression that ER folks enjoy delivering babies.

Up the elevator we go, and get into the room at 4:49 pm. A push or two later, the midwife says, "I think he's coming on the next push." I am completely overwhelmed with emotion, laughing and crying at the same time, as I watch our son Nolan gracefully enter the world. At 4:53 pm.

9lbs 8 oz, 20.5 inches long. Not chump change!


The following day, Tuesday, I managed to get some paperwork faxed to an employer, and by lunch time, I had a favorable job offer from them. What an absolute amazing 24 hours.

Monday, April 21, 2008

Multi-threaded Socket Server in Java

I have always been curious about how to make a multi-threaded server in Java, and it turns out to be pretty simple to get something basic up and running.

My goal was to create a program that would listen for incoming connections from a client, and repeat whatever is sent to that server. You can see this server work using a telnet session on port 5000.

telnet localhost 5000

Then, whatever you type will be echoed back to you. If you want to quit, just type exit.

Here's the code, consisting of 2 classes.

package sockets;

* Includes main method to get things going
* Otherwise, this just prepares a new ServerSocket that
* listens for new connections
* and starts a new thread for each connection
public class EchoServer {
public void go(){
ServerSocket serverSocket = new ServerSocket(5000);
System.out.print("Listening for connections on port 5000... ");
Socket client = serverSocket.accept();
Thread t = new Thread(new EchoClientHandler(client));
System.out.println("Connected - "+client.getInetAddress());
}catch(Exception e){

public static void main(String[] args) {
EchoServer server = new EchoServer();

* The Runnable job that takes in the new Socket
class EchoClientHandler implements Runnable{

private final BufferedReader reader;
private final PrintWriter output;
private final Socket socket;
private static final String MESSAGE = "ECHO... [?]\r\n";
private static final String EXIT_MESSAGE = "Sad to see you go. Goodbye.\r\n";
private static final String WELCOME_MESSAGE = "Welcome to the Echo Server. Type something to see it echoed back to you!\r\n";

public EchoClientHandler(Socket incomingSocket) throws IOException{
socket = incomingSocket;
output = new PrintWriter(incomingSocket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

public void run(){
String line = null;
while((line = reader.readLine()) != null){
boolean quit = false;
output.write(MESSAGE.replaceAll("\\?", line));
quit = true;
}catch(Exception e){
System.err.println("OUCH! "+e.getMessage());
try{socket.close();}catch(Exception ee){}

Here's how it works.

When the EchoServer starts up, it opens a server socket that listens for incoming connection requests. When it gets a request, it creates a new handler instance, taking the Socket as an argument. The handler is a Runnable class, and used to start a new Thread. The result is that the EchoServer can handle more than one connection at a time -- just like a good socket server should.

To expand on this, it would be a good idea to implement some means of managing the threads and connections. Using the java.util.concurrent API would be a good thing to do to implement some means of thread pooling in the server instead of using naked Threads. Thread pooling is an important thing to implement because each new persistent connection requires a new thread. Too many connections would cause some real resource problems. However, if there are limits to the amount of connections the server will allow, you need to manage connections. Therefore, some intelligence might need to be added to a Client program, so that a connection need only stay alive for a certain amount of time before becoming disconnected. Then, a well designed client might seamlessly create a new connection to the server.