《c#网络编程(实例).docx》由会员分享,可在线阅读,更多相关《c#网络编程(实例).docx(117页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、C#与VB.NET网络通信开发实战第1章:套接字编程编写网络应用程序是程序设计中最有趣的领域之。眼看着自己编写的程序成功地通过 网络实现了通信,这是特别令人振奋的。在这一章里,我们将使用TCP/IP建立一个类似于 Windows LiveMessenger (或ICQ)的聊天程序。通过这个聊天程序,你将学会如何在.NET 中进行网络编程,并了解建立多用户聊天程序时会遇到的种种挑战。第2章:串行通信串行通信是设备之间相互通信最古老的机制之一。从!BM PC及其兼容机开始,几乎所 有的计算机都配备了一个或多个串行端口和一个并行端口。顾名思义,串行端口(serial port) 每次1位地连续收发数
2、据,而并行端口(parallel port)则使用8条独立的数据线每次收发8 位数据。尽管串行端口传输速度相对低于并行端口,但串行通信仍然是设备连接的流行选项, 因为它简单而且成本较低。虽然当今的消费产品正在使用USB连接取代串行连接,但是仍 有大量的设备把串行端口作为它们与外部世界连接的唯途径。这一章将介绍怎样使用.NET Framework 2.0 和.NET Compact Framework 2.0 里新的 SerialPort类实现与其他串行设备的通信。我们将建立3个项目,用实例说明怎样使用串行 通信。第一个项目是个聊天程序,它允许(使用串行数据线或者蓝牙互相连接的)两台计 算机进行
3、通信。你可以以此程序为基础,对其进行扩展来实现与手机之类的其他外部串行设 备的通信。你将学会如何通过个串行的蓝牙连接使用AT命令通过程序来控制你的移动电 话。第二个项目是个Pocket PC聊天程序,与前个项目十分类似。第三个项目展示了怎 样与GPS接收器通信,并从中提取有用的数据用于在地图上显示当前位置。第3章:将指纹识别纳入.NET程序生物特征识别是确认个体身份最可靠的方式之一。现在,应该有很多人已经熟悉了微软 指纹阅读器(Microsoft Fingerprint Reader) 使用微软指纹阅读器,你只需把手指放在读取 器上,就能登录你的电脑。你也可以使用指纹阅读器提供的应用程序来为要
4、求身份认证的网 站保存用户!D和密码。随后你就可以将指纹作为钥匙,取出1D和密码,安全地登录那些 站点。微软指纹读取器把需要为不同网站记住不同密码的烦恼扫而尽。在这一章,我们将说明如何使用GrFinger Fingerprint SDK将微软指纹阅读器集成到你 的.NET2.0Windows应用程序中。我们将建立一个来访者鉴别系统,访问办公室的用户可以 使用它在接待处登记。登记以后,下一次他再访问办公室时,只需简单地扫描下指纹,系 统就会记录他的来访。学校也可以改编这个程序用于考勤,比如在大型的阶梯教室等场合, 考勤必须快速而有效地实施。第4章:红外线编程在流行的如WiFi (Wireless
5、 Fidelity,基于IEEE 802.11b标准的无线局域网)、蓝牙和 其他无线技术的喧哗声中,有一种最简单而又最普遍的无线通信形式很容易被忽略它就 是红外线通信。其实只耍用过遥控器就己经用过这种通信形式。红外线通信使用超出光谱中 可见光红光的不可见波段。你可以在应用程序中利用它进行短程的、点到点的数据传输。因 为使用了光,所以光路是使用红外线通信的必要条件。尽管有此限制,红外线还是在数码相 机、PDA和笔记本电脑等设备中日益流行。在这一章里,我们将讲解如何建立允许两台设备(及计算机)使用红外线进行无线通信 的应用程序。你可以将这一章中阐述的编程技术改造并应用到其他编程任务中,如编写无线
6、的网络游戏等。第5章:RFID编程射频识别(Radio Frequency Identifications, RFID)是近来在IT行业大力宣传的项技 术。RFID系统是种识别系统,通过无线电波从称为电子标签(tag)或应答器(transponder) 的设备中接收数据。RFID应用在日常生活中随处可见超市、图书馆、书店等。RFID 提供了一种快速而有效的方式来收集信息,如仓库的库存盘点、物品下落的追踪等。在这一章,我们将介绍如何构建利用RFID技术进行数据采集的Windows应用程序。 我们将使用2个RFID阅读器并分析它们各自的优缺点。第6章:与外围设备交互摄像头是当今大多数人都可以轻易购
7、置的普通外围设备,经常用于视频会议。但是,除 了视频会议以外,还可以用摄像头做些什么呢?对于.NET开发人员来说,答案非常多。而 且你会高兴地看到,将摄像头集成到Windows应用程序中并不像想象中那么难。除了将摄像头集成到应用程序以外,还可以将Windows应用程序连接到诸如传感器这 样的外围设备,以监视周围环境的变化。在这一章,我们通过将Windows程序与外围的传感器和摄像头接口,构建一个可以监 视有害活动的安全系统。你可以探测到入侵者,并用摄像头记录入侵者的行动。目录第I章套接字编程11I套接字编程介绍I12创建自己的多用户聊天应用程序2121为网络通信使用TcpClient和TcpL
8、istener 类 3122构建服务器7123构建客户16124测试聊天应用程序2313构建高级的多用户聊天应用程序2413I定义自己的通信协议24132协议描述24133功能一览25134构建服务器28135构建客户43136测试应用程序6514小结66第2章串行通信6721串行通信基础6822使用串行端U聊天69221硬件需求70222构建聊天应用程序72223创建SerialPort类的实例73224列举所有可用的串口名73225打开串口 75226断开串口连接77227使用串口发送数据78228接收串口上的数据79229测试应用程序802210 传输 Unicode 字符 812211
9、连接到其他串行设备8223在Pocket PC上使用串聊天85231硬件需求86232构建应用程序86233编写程序代码8724用GPS接收器和微软虚拟地球创建地图程序91241构建应用程序94242创建包含虚拟地球地图的HTML文件94243编写程序代码96244显示地图的坐标100245连接到GPS接收器10325绘制保存的路径11226小结118第3章将指纹识别纳入NET程序11931 使用 GrFingerSDK12032创建应用程序120321编写程序代码!23322连接所有控件125323测试应用程序14233小结144第4章红外线编程17141 IrDA 介绍 !7142创建Wi
10、ndows移动设备之间的红外线通信172421你所需要的172422创建项目173423编写程序代码174424接收消息175425显示接收到的消息179426发送消息180427编译并部署应用程序18343建立桌面上的红外线通信184431你所需要的184432创建项目185433导入命名空间186434声明常量和成员变量187435编写Form_Load()事件代码!87436 编写 ReceiveLoop。子程序 188437 编写 ReceiveMessage()函数 189438编写代理以及UpdateTextBox。和 UpdateStatus。子程序 191439 编写 Send
11、Message。子程序 1914310编写Send按钮控件的代码!944311测试应用程序19544小结195第5章RFID编程19751 RFID 介绍 !9752构建考勤应用程序199521 RFID阅读器I: Parallax RFID阅读器模块199522 RF1D电子标签200523阅读器的设置200524构建应用程序用户界面202525编写程序代码207526测试应用程序220527 RFID 阅读器 2: PhidgetRFID221528 RFID电子标签221529构建示例应用程序2225210PhidgetRFID API 2245211编写程序代码2245212测试应用程
12、序2305213两种RF1D阅读器的比较23153小结231第6章与外围设备交互23361所使用的组件233611传感器234612摄像头23462连接传感器到PC235621连接PING传感器236622 PING传感器编程237623与PC集成24063摄像头的编程24664小结2551.1套接字编程介绍第1章套接字编程编写网络应用程序是程序设计中最有趣的领域之。眼看着自己编写的程序成功地通过 网络实现了通信,这是特别令人振奋的。在这一章里,我们将使用TCP/IP建立一个类似于 Windows Live Messenger (或ICQ)的聊天程序。通过这个聊天程序,你将学会如何在.NET
13、中进行网络编程,并了解建立多用户聊天程序时会遇到的种种挑战。1.1 套接字编程介绍套接字(socket)是网络计算机与应用程序之间发送和接收数据的方式的种抽象描述。 它描述了(可能在不同的计算机上,也可能在同一台计算机内的)两个通信点之间的连接。在实际操作中,套接字编程往往TCP/IP和UDP/IP通信相结合(关于TCP/IP和UDP/IP 的更多信息参见下面的“理解IP、TCP和UDP”)。论及套接字编程时,以下3类信息是很 重要的:协议(如 TCP/IP 或 UDP/IP) IP 地址(例如 127.0.0.1) 端口号(例如端口 80) 举例来说,对于http/这样的地址,你应该比较熟悉
14、,这个地址用来指示 Web浏览器加载位于的主页。http指定了使用的应用协议(HTTP使用TCP/IP 传输数据),指定了地址(名称将会被DNS服务器解析成一 个IP地址)。由于HTTP使用端口 80进行通信,端口号80被隐式地指明,故没有出现在地 址里。如图1-1所示,通信的双方都必须拥有IP地址。HTTPCTCPIP)-HTTPCTCPIP”1.2,3.4*-1www. (69.19.15(). 1 ol)*端口 80,端口 8。,E就梦(点击查看大图)图1-1 Web浏览器和网络服务器之间的通信尽管有TCP/IP这样的协议负责把数据从个点传输到另一个点,但所传输数据的内容则需 由诸如HT
15、TP这样的应用协议来指定。在.NET Framework里,套接字通信由Socket类来实现(该类位于System.Net.Sockets命名空 间)。理解IP、TCP和UDP对于网络编程来说,深入地理解当下正在使用的些常见网络协议是很重要的。首先是 网际协议(Internet Protocol, IP)。IP指定了从个点传送到另个点的数据分组(如数据 报datagrams)的格式和寻址方案。假设IP是种邮递系统,你可以通过它把邮件从个地 方寄到另个地方。你只需写上收件者地址并把邮件丢进邮箱里。随后邮局会试图把邮件投 递给收件人。但是,你不能确定你的邮件肯定会到达目的地,也不会知道它究竟何时到
16、达。为了确保邮件被正确地投递,你必须使用额外的服务,比如挂号信。与上述情形类似, 我们需要将其他协议与1P联合使用,以保证数据分组传送无误。传输控制协议(Transmission Control Protocol, TCP)正是这样一种协议。TCP是一种面向连接的网络协议,它(通过应 答机制)保证数据分组可靠并有序地传送。作为流行的网络协议,与1P协同工作的TCP已 被Web浏览器和电子邮件客户这样的应用程序广泛采用。TCP确保了传送的正确性,但它也有不便的地方。正如要花更多的钱来寄送的挂号信 样,TCP给被发送的数据分组加上了额外的报头,增大了分组的尺寸。因此,开发人员 有时会将用户数据报协
17、议(User Datagram Protoeol, UDP)与IP联用。UDP是种无连接的网络协议,同样把数据分组从一点发送到另个点,只有一个例外它并不提供可靠的、 有保障的传送。由于UDP不对传送提供保障,数据分组将包含更多的有效信息并能更快地 传送。使用UDP的开发人员必须建立自己的逻辑以确保数据分组的正确传送。这也与邮寄 的例子很相似:你可以自己给收件人打电话,看他们是否已经收到你寄的邮件。如果他们没 有收到,你可能需要重新寄。对于那些传送小数据分组且不需要数据精确组装的应用程序来 说,UDP是非常有用的。这类程序包括简单文件传输协议(Trivial File Transfer Prot
18、ocol, TFTP)、域名系统(Domain Name System, DNS)以及语音 IP (Voice over IP, VoIP) 1.2创建自己的多用户聊天应用程序1.2 创建自己的多用户聊天应用程序在本章的这一部分,我们将首先建立一个简单的聊天程序,它允许连接到中央服务器的 任何人互相进行通信。这样可以让你探索套接字通信的基本原理,并学习如何向所有已连接 的用户广播消息。1.3 2展示了本章的这一部分将耍的建立的应用程序。(点击査看大图)图1-2即将创建的聊天程序1.2.1 为网络通信使用TcpClient和TepListener类创建聊天程序通常涉及套接字编程创建一个客户和服务
19、器之间的连接,使客户和服 务器都能发送和接收消息。System.Net.Sockets命名空间提供套接字编程所需的功能。在这 个项目我们将使用System.Net.Sockets命名空间里的2个类:TcpClient和T叩Listener。TcpClient类实现了使用TCP发送和接收数据的套接字。因为与远程设备的连接被表示 为流,数据可以使用.NET Framework的流处理技术来读取和写入。TcpListener类以阻塞同步模式提供用于监听和接受外来连接请求的简单方法。下面的示例代码实现了一个简单的等待外来连接的服务器(个控制台应用程序)class Program(/-port numb
20、er to use for listening-const int portNo - 500;static void Main(string args)(System.Net.IPAddress locaLAdd -System.Net.IPAddress.Parse(n127.0.0.1);/-listen at the local address-TcpListener listener = new TcpListener(localAdd, portNo); listener.Start();com/Accepts a pending connection r明TcpClient tcp
21、Client listener.Accebt!汆 1i前f;/-use a Networkstream object to send and receive / data-Networkstream ns tcpC1ient.GetStream();byte data - new bytetcpClient.ReceiveBufferSize;/-read incoming stream; Read() is a blocking call- int numBytesRead ns.Read(data, 0,System.Convert.ToInt32(tcpClient.ReceiveBuf
22、ferSize);/display data received-Console.WriteLine(Received Encoding.ASCII.GetString(data, 0, numBytesRead);/-prevent the console window from closing/ immediately- Console.ReadLine();要连接到服务器并向它发送个字符串,客户代码(个控制台应用程序)将是下面这样的:a 2M5using System;using System.Collections.Generic;using System.Text;using Syst
23、em.Net.Sockets;namespace Client CS(class Program(const int portNo 500;static void Main(string args)( TcpClient tcpclient new TcpClient();/-connect to the server- tcpclient.Connect(0127.0.0.1*, portNo);/-use a Networkstream object to send and receive/ data- NetorkStream ns tcpclient.GetStream(); byte
24、 data Encoding.ASCII.GetBytes(Hello*);/-send the text-ns.Write(data, 0, data.Length);j)技术成就梦想,-connect to the server- tcpclient.Connect(127.0.0.1, portNo),-use a NetworkStream object to send and receive data-一 Dim ns As Networkstream tcpclient.GetStream Dim data As Byte() Encoding.ASCII.GetBytes(Hei
25、lo)-send the text*1mmns.Write(data 0, data.Length)皿$此技术成就梦想End Module注意,Networkstream对象操作字节数组,因而需要使用来自System.Text命名空间的 Encoding.ASCII.GetStringOII Encoding.ASCH.GetBytes。方法来将字节数组转换成字符串, 反之亦然。上面的例子是比较简单的它包含了服务器代码和客户代码。服务器在127.0.0.1使 用端口 500打开个套接字并监听外来TCP连接。当连接建立起来以后,由一个 Networkstream対象读取客户发来的数据。到达的数据
26、随后显示在控制台上。另方面,客 户在127.0.0.1打开个连接,然后使用Networkstream对象向服务器发送个字符串。但是,当服务器需要同时与多个客户通信并能同时发送和接收消息时,问题就会变得复 杂得多。为了实现这些,必须满足以下几条。服务器必须能够与多个客户建立连接。服务器必须能够从客户异步读取数据并能在任何时刻向客户发送消息。客户必须能够从服务器异步读取数据并能在任何时刻向服务器发送消息。接下来的几节将解决这3个问题。1.2.2 构建服务器(1)聊天程序有两个部件服务器和客户,我们来首先构建服务器。用Vistual Studio 2005 创建一个控制台程序项目,将该项目命名为Se
27、rver。在默认的Module 1.vb/Program.cs文件里,首先导入System.Net.Socket命名空间,它包 含这个项目将要用到的所有相关的类。接下来,声明个常量来存储这个应用程序使用的端口号。对这个程序,我们使用端口号500 Visual Basic 2005Module Modulel Const portNo As Integer 500J 2005class ProgrM LCOITI技术成,就琴和const ihf pdrtw $00;提示如果你在服务器(或者客户)上安装了防火墙,请确保打开端口 500,以便这个应用程序运行。我们还需要定义所要监听的本地地址,然后创
28、建一个TcpListener类的实例,用来监听 来自TCP客户的连接。Visual Basic 2005Sub Main()Dim localAdd As System.Net.IPAddress _System.Net.IPAddress.Parse(127.0.0.1)Dim listener As New TcpListener(localAdd, portNo)#2005static void Main(string args)System.Net.IPAddress localAdd 1CTSystem.Net. I PAddress. Parse( 127 丹。D”TcpListe
29、ner listener new TcpListener(localAdd, |JbrtN&);在Main()函数里,使用来自类TcpListener的Strart。方法来开始监听外来连接请求。 AcceptTcpClient。方法是个阻塞式的调用,直到连接建立起来以后程序会继续执行。因 为这个示例里的服务器需要同时为多个客户提供服务,我们将为每一个用户创建一个 ChatClient类(稍后将定义)的实例。服务器将会无限地循环检查,若有客户请求连接,则 接受。Visual Basic 2005Sub Main。Dim localAdd As System.Net.IPAddress 一Syst
30、em.Net.IPAddress.Parse(-127.0.0.1)Dim listener As New Tcplistener(localAdd, portNo) listener. Start。While TrueDim user As New ChatClient(listener.AcceptTcpClient) End WhileEnd Sub02005static void Main(string( args)51CTSystem. Net. IPAddress localAdd 挑 ” System.Net. IPAddress. Parse(T27.6 .舒TcpListen
31、er listener = new TcpListener(localAdd, portNo); listener.Start();while (true)(ChatClient user new|.cChatClient(listener.AcceptTcpClient();)技术成就,想完整的Modulel.vb源文件如下所示。Dim user As New ChatClient(listener.AcceptTcpClient) End While End Sub End ModuleJ 2005using System;using System.Collections.Generic;
32、using System.Text;using System.Met.Sockets;namespace server_CSclass Programconst int portNo 500; static void Main(string args)System.Net.IPAddress localAdd System.Net.IPAddress.Parse(-127.0.0.1);TcpListener listener new listener. Start。J while (true)TcpListenerdocaLAdd, 晔Uq);技术成就梦想ChatClient user -
33、newChatC1ient(1istener.AcceptTcpC1ient();51CT接下来定义ChatClicnt类。我们使用ChatClient类来表示连接到该服务器的每个客户的 信息。在 Visual Studio 2005中为项目添加一个新的类,并将其命名为 ChatClient.vb/ChatClient.cSo 照例,第一步是导入 System.Net.Sockets 命名空间(对于代码的 C#版本,还需要导入System. Collections命名空间)。Visual Bttsic 2005Iiiports System.Net.SocketsC35 I COffl usi
34、ng SyteauWet.Sockets; u s i nfe Sy i tern kolledf iori f;1.2.2构建服务器(2)在ChatClient类中,首先定义各种私有成员(它们的用途在代码注释中会有说明)。同 时声明一个HashTable对象(AllClients),用来保存所有连接到该服务器的用户的列表。将 它声明为共享成员的原因是,确保ChatClient类的所有实例都能够获得当前连接到该服务器 的所有客户的列表。C# 2005class ChatClient(/-contains a list of all the clients-public static Hasht
35、able AllClients = new Hashtable();/-information about the client-private TcpClient _client;private string _clientIP;private string _clientNick;/-used for sending/receiving data-/-is the nickname being sent2*-f,广、; ,目private bool ReceiveNick true, * 当一个客户连接到服务器时,服务器将创建一个ChatClient类的实例,并将变量TcpClient (
36、client)传递给类的构造函数。同时,我们取得客户的IP地址并将它用作索引来标识 HashTable对象中的客户。BeginRead。方法将在独立的线程中启动个从Networkstream对 象(client.GetStream)的异步读取。这样可以使服务器保持响应能力并继续接受来自其他客 户的新连接。读取完成以后,控制将被转移到ReceiveMessage。函数(此函数稍后将会定义)。C2OO5public ChatClient(TcpClient client) (-client - client;/get the client IP address _clientIP c1ient.C
37、1ient.RemoteEndPoint.ToString();add the current client to the hash tableAllClients.Add(_clientIP, this);start reading data from the client in a/ separate threaddata - new byte_client.ReceiveBufferSize;client.GetStream().BeginRead(datd, ,System.Convert.Tolnt32(_client;veBuf rM 的, ReceiveMessage, null
38、);在RcceiveMessage()函数中,苜先调用EndRead()方法来处理异步读取的结尾。在这里,我 们将检查读取的字节数是否小于1。如果是,则意味着客户已经断开连接,那么我们需要从 HashTable对象中(使用客户的IP地址作为我中的索引)删除该客户,同时使用Broadcast。 函数(此函数稍后定义)向所有客户广播消息,告知这特定客户已经离开了聊天。为了简 单起见,假设客户会在第一次连接到服务器时发送他的呢称。此后,只需向所有人广播该客 户发出的所有信息。一旦完成,服务器将再次执行从该客户的异步读取。Broadcast(_clientNick & _ has left the c
39、hat.) End Try End Sub public void ReceiveMessage(IAsyncResult ar)(/-read from client-int bytesRead;trylock (_c1ient.Get St ream()bytesRead 1 ient. Get St ream (). Endead (a r) M q |/-client has disconnected-if (bytesRead - messageReceived);/Zcontinue reading from client- lock ( client.GetStream()(cl
40、ient.GetStream()BeginRead(ddta, 0,System.Convert.Tolnt32(_client.ReceiveBufferSize),ReceiveMessage, null);catch (Exception ex)(AllClients.Remove(_clientIP);Broadcast(_clientNick has left the chat技术成就梦上面的代码里需要注意的一个问题是,需要使用SyncLock (C#中的lock)语句来阻止 多个线程同时使用Networkstream对象。当服务器连接到多个客户而且它们全都在同一时刻 试图访问Net
41、workstream对象时,这情况就可能会出现。SendMessage。函数允许服务器向客户发送消息。0 2005public void SendMessage(string message)Itry( /-send the text- System.Net.Sockets.NetworkStream ns;lock (_c1ient.Get St ream()(ns c1ient.GetStream();)byte bytesToSend System.!ext.Encoding.ASCII.GetBytes(message); ns.Write(bytes!oSend, 0, bytes!
42、oSend.Length); ns.Flush();)catch (Exception ex)mmConsole.WriteLine(ex.!oString();)技术成就梦想最后,Broadcast。函数向存储在AllClients HashTable对象中的所有客户发送消息。Visual Basic 2005Public Sub Broadcast(ByVai message As String) ,log it locally-Console.WriteLine(message) Dim c As DictionaryEntry For Each c In AllClients,-bro
43、adcast Message to all users-CType(c.Value, 一ChatC1ient).SendMessage(message & vblf) NextEnd SubC,2005public void Broadcast(string message)/-log it locally- LCOHlConsoleHriteline(iiessagr1 七 ;aforeach (Diet ionaryEntryv ArrCHenf%)回/-broadcast message to all users-(ChatClieit)(c.Value) ).Send!ess4gft4
44、message + Environment.HewLinejf :ft月1.2.3构建客户(1)现在服务器已经构建起来,接下来构建客户。使用Visual Studio 2005创建一个新的 Windows应用程序(将它命名为WinClient),并在默认窗体上放置如图1-3所示的控件。 设置 txtMessage History 控件的 MultiLine 和 Readonly 属性为 True,并设置其 ScrollBars 属客户应用程序的逻辑与服务器类似,不过更加直接。双击表单切换到编辑窗口,导入以下命 名空间。Visual Basic 2005Imports System.Net.SocketsC# 200551CTusing System.Net.Sockets; L在类Forml里定义下列常量和变量。C2