原理:电话预订功能,需要显示来电者的电话号码,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
文件既可以在本文附件处下载(仅含本程序使用到的三个文件),也可以到广州高深商电子技术有限公司主页免费下载。
硬件:来电显示连接盒(来电宝)
来电管理部分,主要实现来电的获取与显示
InBlock.gif  //tfq-9-8----来电管理------ 
InBlock.gif                TeleMan teleMan =  new TeleMan(); 
InBlock.gif                 string teleNumber = ""; 
InBlock.gif                Thread th; 
InBlock.gif                 //------------------------ 
InBlock.gif# region ----------来电管理-------------------------- 
InBlock.gif                 //运行TeleListen.exe 
InBlock.gif                 public  void runTeleExe() 
InBlock.gif                { 
InBlock.gif                         string path =  "../../tele/TeleListen.exe"
InBlock.gif 
InBlock.gif                        FileInfo fi =  new FileInfo(path); 
InBlock.gif                         if (fi.Exists) 
InBlock.gif                        { 
InBlock.gif                                Process.Start(fi.FullName); 
InBlock.gif 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif                 //结束Telelisten.exe 
InBlock.gif                 public  void killTeleExe() 
InBlock.gif                { 
InBlock.gif                        Process[] process = Process.GetProcessesByName( "TeleListen"); 
InBlock.gif                        process[0].Kill(); 
InBlock.gif                } 
InBlock.gif                 //来电监听与获取 
InBlock.gif                 public  void teleListen(Object o) 
InBlock.gif                { 
InBlock.gif 
InBlock.gif                        teleMan.connect(); 
InBlock.gif                         while ( true
InBlock.gif                        { 
InBlock.gif                                teleNumber = teleMan.getTeleNumber(); 
InBlock.gif 
InBlock.gif                                 if (tbSchePhone.InvokeRequired) 
InBlock.gif                                { 
InBlock.gif                                        showTeleNumberDelegate showd =  new showTeleNumberDelegate(showTeleNumber); 
InBlock.gif                                         this.Invoke(showd,  new  object[] { teleNumber }); 
InBlock.gif                                } 
InBlock.gif 
InBlock.gif                        } 
InBlock.gif 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 //在控件上显示来电 
InBlock.gif                 private  void showTeleNumber( string number) 
InBlock.gif                { 
InBlock.gif                        tbSchePhone.Text = number; 
InBlock.gif 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 //委托 
InBlock.gif                 delegate  void showTeleNumberDelegate( string s); 
InBlock.gif                # endregion
TelMan.cs
InBlock.gif  public  class TeleMan 
InBlock.gif        { 
InBlock.gif                 int port = 3825; 
InBlock.gif                 string host =  "127.0.0.1"
InBlock.gif                 string teleNumber = ""; 
InBlock.gif                Socket s; 
InBlock.gif 
InBlock.gif                 public  void connect() 
InBlock.gif                { 
InBlock.gif                        /**/ 
InBlock.gif                         ///创建终结点(EndPoint) 
InBlock.gif                        IPAddress ip = IPAddress.Parse(host); //把ip地址字符串转换为IPAddress类型的实例 
InBlock.gif                        IPEndPoint ipe =  new IPEndPoint(ip, port); //用指定的端口和ip初始化IPEndPoint类的新实例 
InBlock.gif 
InBlock.gif                        /**/ 
InBlock.gif                         ///创建socket并连接到终结点 
InBlock.gif                        s =  new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建一个socket对像,如果用udp协议,则要用SocketType.Dgram类型的套接字 
InBlock.gif 
InBlock.gif                         try 
InBlock.gif                        { 
InBlock.gif                                s.Connect(ipe); 
InBlock.gif                        } 
InBlock.gif                         catch (SocketException e) 
InBlock.gif                        { 
InBlock.gif                                Console.WriteLine(e.Message); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 //关闭连接 
InBlock.gif                 public  void close() 
InBlock.gif                { 
InBlock.gif                         try 
InBlock.gif                        { 
InBlock.gif                                s.Close(); 
InBlock.gif                        } 
InBlock.gif                         catch (SocketException e) 
InBlock.gif                        { 
InBlock.gif                                Console.WriteLine(e.Message); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 //获取电话号码 
InBlock.gif                 public  string getTeleNumber() 
InBlock.gif                { 
InBlock.gif                         try 
InBlock.gif                        { 
InBlock.gif                                 //接收数据 
InBlock.gif                                 string recvStr = ""; 
InBlock.gif                                 byte[] recvBytes =  new  byte[1024]; 
InBlock.gif                                 int bytes; 
InBlock.gif                                bytes = s.Receive(recvBytes, recvBytes.Length, 0); //从服务器端接受返回信息 
InBlock.gif                                recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes); 
InBlock.gif 
InBlock.gif                                 if (recvStr.Contains( "#")) 
InBlock.gif                                { 
InBlock.gif                                         //Console.WriteLine(recvStr); 
InBlock.gif                                         //截取电话号码 
InBlock.gif                                         /* 收到的数据字符串是下面这种格式: 
InBlock.gif                                         * #013270127645@1-2 2009-09-08 13:20:00 
InBlock.gif                                         * 但第一次收到的数据字符串前面是一段" ...connect successfully.."的信息 
InBlock.gif                                         */
 
InBlock.gif                                         int startIndex = recvStr.IndexOf( "#"); 
InBlock.gif                                         int endIndex = recvStr.IndexOf( "@"); 
InBlock.gif 
InBlock.gif                                        teleNumber = recvStr.Substring(startIndex + 1, endIndex - startIndex - 1); 
InBlock.gif                                         // Console.WriteLine(teleNumber); 
InBlock.gif                                } 
InBlock.gif                        } 
InBlock.gif                         catch (SocketException e) 
InBlock.gif                        { 
InBlock.gif                                 //Console.WriteLine(e.Message); 
InBlock.gif                        } 
InBlock.gif                         return teleNumber; 
InBlock.gif 
InBlock.gif                } 
InBlock.gif        }
代码中的Socket服务的连接、关闭, TeleListen.exe的运行,cdTele.dll的调用,原理部分都有叙述。
还可以参考以下在没有安装来电显示盒的计算机上获取来电的情况之下实现来电显示及来电监听、保存号码等功能的实现,还提供了JAVA使用Socket读取来电号码的示例使用C#的Socket开发网络版来电管理软件的简单示例C++Builder使用Socket读取来电号码的示例使用VB的Socket开发网络版来电管理软件的简单示例等内容,文中均提供代码下载和基本原理的讲解(以上示例均是没有使用来电显示盒的情况),可以通过这些文章进一步了解其实现原理。