Serial Communications:
A C++ Developer's Guide,
2nd Edition

by Mark Nelson
IDG Books Worldwide, May 2000
ISBN 0-76454-570-1
864 pages.
List price in the US is $49.99

First Edition

The page for the first edition is still on line. You can read it at this link. The first edition has been out of print for some time, so you probably won't find this page much use.

Availability

Unfortunately, this book is out of print. However, you can frequently find used copies available on Amazon.com for reasonable prices. Be sure to order the second edition. If you use the link posted here, you will be helping me with the costs of keeping this web site up and running. Thanks!  

Errata

The 32 bit code in this book was developed for the most part with Visual C++ 5. Readers have run into a few compiler glitches with Visual C++ 6. If you use VC++ 6, please be sure to apply all of Microsoft's service packs. At this time, the latest is SP3. You can download these from the Microsoft web site. (I'd provide a link, but Microsoft changes their web page often enough to make this an exercise in frustration.

Chapter 1

Figure 1-5 on Page 10 has an extra 0 bit in the middle of the world. There should be a string of 5, not six. Here's an improved version of the image:

Chapter 11

Win32Port.h

If you are developing for a Windows 2000 target, or for NT 4 with SP3 or later, you will need to modify a single line in Win32Port.h. Around line 76 of this file, you will find a line of code that looks like this:

C++:
  1. enum { EV_RINGTE = 0x2000 }

Change it to look like this:

C++:
  1. enum { EV_RINGTE = 0 }

This flag is used to get the serial driver to report changes on the input RLSD (ringer) control line under Windows 9X. This undocumented feature allows things to work properly in that environment, but breaks things under Windows 2000.

Keep in mind that if you make this change, your program won't respond to incoming rings under Win32, unless you watch for "RING" messages coming from your modem. (Watching for messages is probably a better way to do it in general, so maybe it's time to change!)

If you are deploying your code on both Windows 2K and Windows 9X, you might want to create a more general purpose solution by determining whether or not to use the EV_RINGTE mask at runtime, based on detection of the O/S type.

Win32Port.cpp

I botched the definition of a loop in this code, and despite the compiler warning, I failed to note the problem until alerted by several readers.

The loop in output_worker() used to start like this:

C++:
  1. for ( bool done = false ; ; !done ) {

Now it starts like this:

C++:
  1. for ( bool done = false ; !done ; ) {

Chapter 12

For some reason, the publisher decided to leave this chapter's executable off the CD-ROM. This shouldn't be a big deal, since you ought to be able to build it with the included project file. But, just in case you can't, here is the executable. Note that this is built with debug options turned off.

Chapter 13

There are a few errors that showed up in this project in Visual C++ 6. They are all related to minor changes in header files or the way the compiler parses them.

Win32Term.cpp

In Win32Term::Paint(), a call to SelectObject() needed a cast of the return type before it could be assigned to hOldFont. The line was:

C++:
  1. HFONT hOldFont = SelectObject( hDC, m_hFont ) ;

It is now

C++:
  1. HFONT hOldFont = (HFONT) SelectObject( hDC, m_hFont );

Win32Term.h

I use a pragma in this header file to turn off compiler warnings for error C4786, which are unavoidable, and are really pointing to problems in the compiler, not in my code. In VC++ 6, the pragma has to be moved to be ahead of the #include for header file vector. The resulting code now looks like this:

C++:
  1. //
  2. // The vector<vector<>> variables in this class
  3. // end up with incredibly long expanded names. This
  4. // pragma disables the associated warnings
  5. //
  6. #pragma warning( disable : 4786 )
  7.  
  8. #include <windows.h>
  9. #include <vector>
  10. using namespace std;

Download changed files

Win32Term.cpp
Win32Term.h
Win32Port.cpp
Win32Port.h

You should be able to build the new executable by coping these files to the correct locations.

Chapter 16

Bill Jacques noticed that the SendSingleFile() function in Zmodem.cpp gets stuck in an infinite loop if the remote end has an allocation problem. He sends an update of the function (as a Word Doc.) Bill wrote a Win32-specific version of the function, so don't try to include this code if you are running in some other environment.

You will have to replace the existing function in Zmodem.cpp.