原理:电话预订功能,需要显示来电者的电话号码,c#实现获取电话号码,并在应用程序中显示出来。将电话机通过支持来电显示的modermUSB来电显示盒(来电宝)与电话线连接,即可实现来电显示功能。
服务程序提供了Socket服务和查询函数,软件开发者可利用Socket服务DLL提供的接口函数进行查询、获取来电信息。
TeleListen.exe工作原理如下:监听来电显示管理器,并把来电号码存放在来电池中;如果有Scoket的客户端连接,则当有来电时:(1)设置了自动发送来电,则向客户端发送来电号码和来电时间;(2)否则向客户端发送“call”,通知客户端已经有来电,客户端向服务程序发送“get”指令,获取来电号码。同时提供DLL的查询接口,其它程序也可通过函数查询和索取来电号码。
什么是来电池:

来电池是指监听程序内的一个数组 [0..100],用来保存来电号码和来电时间。数组从0开始计数,把第1个来电号码保存在第0个数据单元,把第2个来电号码保存在第1个数据单元,如此类推。当取走来第1个来电号码(第0个数据单元)后,自动把第2个号码移位到第0个数据单元,如此类推。
TeleListen.exe使用方式:是一个执行文件,用来监听电话来电,并提供SocketDLL调用服务。如果希望多台计算机同时显示来电客户信息,最好在连接来电显示盒的计算机上,把此文件放在系统的启动组中,或修改注册表来让系统自动运行。运行后在屏幕的左下脚有一个图标,可设置运行状态。
cdTele.dll使用方式(提供查询和获取来电号码的函数:
    1
启动程序时调用OpenMapFileStartTeleListen

    2
打开来电管理器COM端口:OpenComPort;如果服务程序状态设置为自动打开端口,则这一步可省略。

    3
检查是否有来电:CountShareData;这一步不是必须的。

    4
使用GetShareNoGetShareData获取来电;可定时(例如每隔1秒)不断使用GetShareData(0)获取来电号码。也可定义回调函数DoTeleComing,在有来电时自动调用。

    5
结束程序时调用CloseMapFileStopTeleListen
Socket服务:服务程序提供Socket服务(默认),最大可连接数为5Socket默认端口为3825;可通过修改ini(状态设置)来禁止Socket服务和改变Socket端口号。使用方法:
    1
使用ClientSocket连接服务器。如果是本机,ClientSocketIP地址设为127.0.0.1,端口设为3825

    2
与服务器建立连接后,如果有来电,服务器返回call nn表示目前有第n个来电。

    3
当有来电时,发送指令get到服务器,服务器返回来电号码。如果有多个来电(n>0),可多次使用get指令。

    4
服务器响应get指令,返回来电号码。

    5
退出程序时请关闭Socket连接。
文件:
    cdTele.dll      
来电号码查询动态库

    TeleListen.exe  
来电显示监听程序,适合于Windows98及以上的版本
TeleListen.ini
文件既可以在本文附件处下载(仅含本程序使用到的三个文件),也可以到广州高深商电子技术有限公司主页免费下载。
硬件:来电显示连接盒(来电宝)
来电管理部分,主要实现来电的获取与显示
//tfq-9-8----来电管理------
                TeleMan teleMan = new TeleMan();
                 string teleNumber = "";
                Thread th;
                 //------------------------
# region ----------来电管理--------------------------
                 //运行TeleListen.exe
                 public void runTeleExe()
                {
                         string path = "../../tele/TeleListen.exe";

                        FileInfo fi = new FileInfo(path);
                         if (fi.Exists)
                        {
                                Process.Start(fi.FullName);

                        }
                }
                 //结束Telelisten.exe
                 public void killTeleExe()
                {
                        Process[] process = Process.GetProcessesByName( "TeleListen");
                        process[0].Kill();
                }
                 //来电监听与获取
                 public void teleListen(Object o)
                {

                        teleMan.connect();
                         while ( true)
                        {
                                teleNumber = teleMan.getTeleNumber();

                                 if (tbSchePhone.InvokeRequired)
                                {
                                        showTeleNumberDelegate showd = new showTeleNumberDelegate(showTeleNumber);
                                         this.Invoke(showd, new object[] { teleNumber });
                                }

                        }

                }

                 //在控件上显示来电
                 private void showTeleNumber( string number)
                {
                        tbSchePhone.Text = number;

                }

                 //委托
                 delegate void showTeleNumberDelegate( string s);
                # endregion
TelMan.cs
public class TeleMan
        {
                 int port = 3825;
                 string host = "127.0.0.1";
                 string teleNumber = "";
                Socket s;

                 public void connect()
                {
                        /**/
                         ///创建终结点(EndPoint)
                        IPAddress ip = IPAddress.Parse(host); //把ip地址字符串转换为IPAddress类型的实例
                        IPEndPoint ipe = new IPEndPoint(ip, port); //用指定的端口和ip初始化IPEndPoint类的新实例

                        /**/
                         ///创建socket并连接到终结点
                        s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建一个socket对像,如果用udp协议,则要用SocketType.Dgram类型的套接字

                         try
                        {
                                s.Connect(ipe);
                        }
                         catch (SocketException e)
                        {
                                Console.WriteLine(e.Message);
                        }
                }

                 //关闭连接
                 public void close()
                {
                         try
                        {
                                s.Close();
                        }
                         catch (SocketException e)
                        {
                                Console.WriteLine(e.Message);
                        }
                }

                 //获取电话号码
                 public string getTeleNumber()
                {
                         try
                        {
                                 //接收数据
                                 string recvStr = "";
                                 byte[] recvBytes = new byte[1024];
                                 int bytes;
                                bytes = s.Receive(recvBytes, recvBytes.Length, 0); //从服务器端接受返回信息
                                recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);

                                 if (recvStr.Contains( "#"))
                                {
                                         //Console.WriteLine(recvStr);
                                         //截取电话号码
                                         /* 收到的数据字符串是下面这种格式:
                                         * #013270127645@1-2 2009-09-08 13:20:00
                                         * 但第一次收到的数据字符串前面是一段" ...connect successfully.."的信息
                                         */

                                         int startIndex = recvStr.IndexOf( "#");
                                         int endIndex = recvStr.IndexOf( "@");

                                        teleNumber = recvStr.Substring(startIndex + 1, endIndex - startIndex - 1);
                                         // Console.WriteLine(teleNumber);
                                }
                        }
                         catch (SocketException e)
                        {
                                 //Console.WriteLine(e.Message);
                        }
                         return teleNumber;

                }
        }
代码中的Socket服务的连接、关闭, TeleListen.exe的运行,cdTele.dll的调用,原理部分都有叙述。
还可以参考以下在没有安装来电显示盒的计算机上获取来电的情况之下实现来电显示及来电监听、保存号码等功能的实现,还提供了JAVA使用Socket读取来电号码的示例、使用C#的Socket开发网络版来电管理软件的简单示例C++Builder使用Socket读取来电号码的示例、使用VB的Socket开发网络版来电管理软件的简单示例等内容,文中均提供代码下载和基本原理的讲解(以上示例均是没有使用来电显示盒的情况),可以通过这些文章进一步了解其实现原理。