logo资料库

C#中TCP通讯的实现方法.pdf

第1页 / 共24页
第2页 / 共24页
第3页 / 共24页
第4页 / 共24页
第5页 / 共24页
第6页 / 共24页
第7页 / 共24页
第8页 / 共24页
资料共24页,剩余部分请下载后查看
C#中 TCP 通讯的实现方法 Socket 就是套接字,它是网络编程中最常用遇到的概念和工具。在 TCP/IP 网络中, 传送和接收数据就会经常使用到 Socket,由于使用 Socket 能够在网络上处理复杂数据, 所以在各种网络应用程序中,涉及到数据传送和接收,一般都会使用 Socket,可见要掌 握网络编程,精通 Socket 是非常重要。由于 Socket 本身的复杂性,决定了掌握它是比 较困难的。Visual C#是微软公司推荐的开发.Net 平台应用程序的主要语言,随着.Net 的深入人心,目前很多有远见的公司都把以前的软件转向了.Net 平台。掌握网络编程始 终是学习一种开发语言的重点,这一点对于 Visual C#也同样如此。Visual C#实现网络 功能其关键也是掌握托管 Socket 的使用方法。本文就来详细介绍 Visual C#中利用托管 Socket 实现网络数据传送和接收的实现方法及其注意事项。 一.简介 Socket: Socket 诞生于上个世纪 80 年代初,美国政府的高级研究工程机构(ARPA)给加利 福尼亚大学伯克力(Berkeley)分校提供了资金,委托他们在 UNIX 操作系统下实现 TCP/IP 协议的开发接口。于是研发人员就为 TCP/IP 网络通信开发了一个 API(应用程 序接口)。这个 API 称为 Socket 接口(套接字)。所以有时候说,Socket 是 TCP/IP 上的 API。 到了上个世纪 90 年代,当时的一些网络开发商,包括现在地 Sun 和 Microsoft 公司 等,共同制定了一套 WINDOWS 下的网络编程接口,即 WindowsSockets 规范,简称 WinSock 规范。WinSock 规范是一套开放的、支持多种协议的 Windows 下的网络编程接 口。从 1991 年的 1.0 版到 1995 年的 2.0.8 版,经过不断完善并在 Intel、Microsoft、Sun 等公司的大力支持下,已成为 Windows 网络编程的事实上的标准。目前,WinSock 规范 主要有 1.1 版和 2.0 版。两者的最重要区别是 1.1 版只支持 TCP/IP 协议,而 2.0 版可以 支持多协议。2.0 版有良好的向后兼容性,任何使用 1.1 版的源代码,二进制文件,应用 程序都可以不加修改地在 2.0 规范下使用。 可见 Socket 接口其实是 TCP/IP 网络的 API 接口函数,Socket 数据传输其实就是一 种特殊的 I/O。常用的 Socket 类型有两种:流式 Socket(SOCK_STREAM)和数据报式 Socket(SOCK_DGRAM)。流式是一种面向连接的 Socket,针对于面向连接的 TCP 服 务应用;数据报式 Socket 是一种无连接的 Socket,对应于无连接的 UDP 服务应用。 二.Visual C#中操作 Socket: 虽然 Visual C#可以使用 NetworkStream 来传送、接收数据,但 NetworkStream 在 使用中有很大的局限性,利用 NetworkStream 只能传送和接收字符类型的数据,如果要 传 送 的 是 一 些 复 杂 的 数 据 如 : 二 进 制 数 据 等 , 它 就 显 得 能 力 有 限 了 。 但 使 用 NetworkStream 在处理自身可操作数据时,的确要比 Socket 方便许多。Socket(套接字) 几乎可以处理任何在网络中需要传输的数据类型。
我们知道 Visual C#和 Visual C++的区别之一,就是 Visual C#没有属于自己的类 库,而 Visual C++却是有的,Visual C#使用的类库是.Net 框架为所有开发.Net 平台程 序语言提供的一个公用的类库——.Net FrameWork SDK。Visual C#主要网络功能主要 使 用 .Net FrameWork SDK 中 的 提 供 的 二 个 命 名 空 间 “ System.Net.Sockets ” 和 “System.Net”。而实现 Socket 使用的是命名空间“System.Net.Sockets”中的 Socket 类。 Visual C#通过创建 Socket 类的实例来实现 Socket 的托管版本。在 Visual C#中创建完 Socket 实例后,可以通过此 Socket 实例的 Bind 方法绑定到网络中指定的终结点,也可 以通过其 Connect 方法向指定的终结点建立的连接。连接创建完毕,就可以使用其 Send 或 SendTo 方法将数据发送到 Socket;同样使用其的 Receive 或 ReceiveFrom 方法从 Socket 中读取数据。在 Socket 使用完毕后,请使用其的 Shutdown 方法禁用 Socket,并使用 Close 方法关闭 Socket。表 01 和表 02 是 Socket 类中的常用属性和方法及其简要说明。 属性 说明 AddressFamily 获取 Socket 的地址族。 Available 获取已经从网络接收且可供读取的数据量。 Blocking 获取或设置一个值,该值指示 Socket 是否处于阻塞模式。 Connected 获取一个值,该值指示 Socket 是否已连接到远程资源。 Handle 获取 Socket 的操作系统句柄。 LocalEndPoint 获取本地终结点。 ProtocolType 获取 Socket 的协议类型。 RemoteEndPoint 获取远程终结点。 SocketType 获取 Socket 的类型。 表 01:Socket 类的常用属性及其说明 方法 Accept 说明 创建新的 Socket 以处理传入的连接请求。 BeginAccept 开始一个异步请求,以创建新的 Socket 来接受传入的连接请求。 BeginConnect 开始对网络设备连接的异步请求。 BeginReceive 开始从连接的 Socket 中异步接收数据。 BeginReceiveFrom 开始从指定网络设备中异步接收数据。 BeginSend 将数据异步发送到连接的 BeginSendTo 向特定远程主机异步发送数据。 Bind 使 Socket 与一个本地终结点相关联。
Close Connect 强制 Socket 连接关闭。 建立到远程设备的连接。 EndAccept 结束异步请求以创建新的 Socket 来接受传入的连接请求 EndConnect 结束挂起的异步连接请求。 EndReceive 结束挂起的异步读取。 EndReceiveFrom 结束挂起的、从特定终结点进行异步读取。 EndSend 结束挂起的异步发送 EndSendTo 结束挂起的、向指定位置进行的异步发送。 GetSocketOption 返回 Socket 选项的值。 IOControl 为 Socket 设置低级别操作模式 Listen Poll Receive 将 Socket 置于侦听状态。 接收来自连接 Socket 的数据。 ReceiveFrom 接收数据文报并存储源终结点。 Select Send SendTo 确定一个或多个套接字的状态。 将数据发送到连接的 将数据发送到特定终结点。 SetSocketOption 设置 Socket 选项。 Shutdown 禁用某 Socket 上的发送和接收。 表 02:Socket 类的常用方法及其说明 其中“BeginAccept”和“EndAccept”、“BeginConnect”和“EndConnect”、 “BeginReceive”和“EndReceive”、“BeginReceiveFrom”和“EndReceiveFrom”、 “BeginSend”和“EndSend”、“BeginSendTo”和“EndSendTo”是六组异步方法, 其功能分别相当于“Accept”、“Connect”、“Receive”、“ReceiveFrom”、 “Send”和“SendTo”方法。 下面就通过一个具体的示例,来介绍 Visual C#中如何通过托管 Socket 实现数据传送和 接收的具体方法。 本文示例其实是由二部分组成,也可以看成是客户机程序和服务器程序。客户机程序功 能是通过
Socket 向服务器程序创建连接,并在连接完成后,向服务器发送数据;服务器程序通过 侦听端口,接受网络的 Socket 的连接请求,并在连接完成后,接收从客户机发送来的数 据,并显示出来。下面首先来介绍 Visual C#通过托管 Socket 实现客户机程序的具体方 法。 三.本文介绍程序的设计、调试、运行的软件环境: (1).微软公司视窗 2000 服务器版 (2).Visual Studio .Net 正式版,.Net FrameWork SDK 版本号 3705 四.利用 Socket 来传送数据: Visual C#在使用 Socket 传送数据时要注意下列问题的解决方法: 1.创建 Socket 实例,使用此实例创建和远程终结点的连接,并判断连接是否成功建立。 2.发送数据到 Socket,实现数据传送。 这些问题解决方法都可以在下面介绍代码中找到相对应的部分。由于下面的代码都有详 细的注解, 这里就不详细介绍。下面是利用 Socket 传送数据的具体实现步骤: 1.启动 Visual Studio .Net,并新建一个 Visual C#项目, 项目名称为【利用 Socket 来发送数据】。 2.把 Visual Studio .Net 的当前窗口切换到【Form1.cs(设计)】窗口, 并从【工具箱】中的【Windows 窗体组件】选项卡中往 Form1 窗体中拖入下列组件,并 执行相应操作: 二个 TextBox 组件,一个用以输入远程主机的 IP 地址,一个用以输入往远程主机传送 的数据。 一个 StausBar 组件,用以显示程序的运行状况。 一个 ListBox 组件,用以显示程序已传送的数据信息。 三个 Label 组件。 二个 Button 组件,名称分别为 button1、button2,并在这二个组件被拖入窗体后,分别
双击它们,则系统会在 Form1.cs 文件中自动产生这二个组件的 Click 事件对应的处理代 码。 3.【解决方案资源管理器】窗口中,双击 Form1.cs 文件,进入 Form1.cs 文件的编辑界面。 4.以下面代码替代系统产生的 InitializeComponent 过程: private void InitializeComponent ( ) { ( ) ; ( ) ; this.label1 = new System.Windows.Forms.Label ( ) ; this.textBox1 = new System.Windows.Forms.TextBox this.button1 = new System.Windows.Forms.Button ( ) ; this.label2 = new System.Windows.Forms.Label ( ) ; this.textBox2 = new System.Windows.Forms.TextBox this.listBox1 = new System.Windows.Forms.ListBox ( ) ; this.statusBar1 = new System.Windows.Forms.StatusBar ( ) ; this.label3 = new System.Windows.Forms.Label ( ) ; this.button2 = new System.Windows.Forms.Button ( ) ; this.SuspendLayout ( ) ; this.label1.Location = new System.Drawing.Point ( 24 , 20 ) ;
this.label1.Name = "label1" ; this.label1.Size = new System.Drawing.Size ( 74 , 30 ) ; this.label1.TabIndex = 0 ; this.label1.Text = "IP 地址:" ; this.textBox1.BorderStyle = System.Windows. Forms.BorderStyle.FixedSingle ; this.textBox1.Location = new System.Drawing.Point ( 94 , 18 ) ; 21 ) ; this.textBox1.Name = "textBox1" ; this.textBox1.Size = new System.Drawing.Size ( 166 , this.textBox1.TabIndex = 1 ; this.textBox1.Text = "" ; this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat ; this.button1.Location = new System.Drawing.Point ( 280 , 14 ) ; 28 ) ; this.button1.Name = "button1" ; this.button1.Size = new System.Drawing.Size ( 62 , this.button1.TabIndex = 2 ; this.button1.Text = "连接" ;
this.button1.Click += new System.EventHandler ( this.button1_Click ) ; this.label2.Location = new System.Drawing.Point ( 16 , 64 ) ; this.label2.Name = "label2" ; this.label2.TabIndex = 3 ; this.label2.Text = "发送信息:" ; this.textBox2.BorderStyle = System.Windows. Forms.BorderStyle.FixedSingle ; this.textBox2.Location = new System.Drawing.Point ( 94 , 58 ) ; this.textBox2.Name = "textBox2" ; this.textBox2.Size = new System.Drawing.Size ( 166 , this.textBox2.TabIndex = 4 ; this.textBox2.Text = "" ; this.listBox1.ItemHeight = 12 ; this.listBox1.Location = new System.Drawing.Point ( 20 , this.listBox1.Name = "listBox1" ; this.listBox1.Size = new System.Drawing.Size ( 336 , 21 ) ; 118 ) ; 160 ) ;
this.listBox1.TabIndex = 6 ; this.statusBar1.Location = new System.Drawing.Point ( 0 , 295 ) ; 22 ) ; 94 ) ; this.statusBar1.Name = "statusBar1" ; this.statusBar1.Size = new System.Drawing.Size ( 370 , this.statusBar1.TabIndex = 7 ; this.statusBar1.Text = "无连接" ; this.label3.Location = new System.Drawing.Point ( 14 , this.label3.Name = "label3" ; this.label3.Size = new System.Drawing.Size ( 128 , 23 ) ; this.label3.TabIndex = 8 ; this.label3.Text = "已经发送的信息:" ; this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat ; this.button2.Location = new System.Drawing.Point ( 280 , 54 ) ; this.button2.Name = "button2" ; this.button2.Size = new System.Drawing.Size ( 62 , 28 ) ; this.button2.TabIndex = 9 ;
分享到:
收藏