Channel coding is an error-control technique used for providing robust data transmission through imperfect channels by adding redundancy to the data. Such coding methods are made up of two important classes — block codes and convolutional codes. The goal of this paper is to provide an overview of both classes and to review the astounding strides that have been made in this decade toward approaching the theoretical limitations of what is possible. Forward error correction (FEC) is the name used when the receiving equipment does most of the work. For block codes, the decoder looks for errors, and once detected, corrects them (according to the capability of the code). The technique has become an important signal-processing tool used in modern communication systems, and in a wide variety of other digital applications, such as high-density memory and recording media. Channel coding provides system performance improvements at significantly lower cost than through the use of other methods that increase signal-to noise ratio (SNR), such as increased power or antenna gain.