五.利用Socket来接收数据:
Visual C#在使用Socket来介绍网络传送来的数据时,要解决下面三个问题,也是完成Visual C#使用Socket来接收数据的三个步骤:
1.侦听网络,接受网络连接申请;
2..获得用以接收数据的Socket实例,并以此实例接收远程主机发送来的数据;
3.根据远程主机发送来的控制码,断开网络连接,并清除资源。
此处接收接收数据,是上面介绍的【利用Socket来传送数据】传送来的数据。
下面就是利用Socket来接收数据的具体实现步骤:
1.启动Viisual Studio .Net,并新建一个Visual C#项目,项目名称为【利用Socket来接收数据】。
2.把Visual Studio .Net的当前窗口切换到【Form1.cs(设计)】窗口,并从【工具箱】中的【Windows窗体组件】选项卡中往Form1窗体中拖入下列组件,并执行相应操作:
一个ListBox组件,用以显示接收的数据。
一个StausBar组件,用以显示接收端程序的运行状况。
一个Button组件,名称为button1,并在这个组件被拖入窗体后,双击它,则系统会在Form1.cs文件中自动产生其Click事件对应的处理代码。
3.【解决方案资源管理器】窗口中,双击Form1.cs文件,进入Form1.cs文件的编辑界面。
4.以下面代码替代系统产生的InitializeComponent过程::
至此【利用Socket来接收数据】项目设计后的界面就完成了,具体如图02所示:
图02:【利用Socket来接收数据】项目的设计界面
5.把Visual Studio .Net的当前窗口切换到Form1.cs的代码编辑窗口,并在Form1.cs文件的开头,用下列导入命名空间代码替代系统缺省的导入命名空间代码。
6.在Form1.cs中的class代码区中添加下列代码,下列代码的作用是定义全局变量和创建全局使用的实例:
7.在Form1.cs中的Main函数之后,添加下列代码,下列代码的作用是定义过程“Listen”,此过程的功能是监听“8000”端口号,接收网络中连接请求,建立连接,并获取接收数据时使用的Socket实例,并以Socket实例来接收客户机程序发送来的数据。并根据客户机发送来控制码来断开网络连接,释放资源:
8.用下列代码替换Form1.cs中的button1组件的Click事件对应的处理代码,下面代码是以刚刚定义“Listen”过程来初始化线程实例thThreadRead,并启动这个线程:
至此,在保存上述的所有修改步骤之后。一个基于TCP协议的、利用Socket接收端程序的就完成了。图03和图04分别是上述二个示例运行后的界面
图03:【利用Socket来传送数据】的运行界面
图04:【利用Socket来接收数据】的运行界面
六.总结:
.Net FrameWork SDK中的Socket类的功能是非常强大的,要十分详细的介绍它,非一篇文章所能达到,本文所窥探的也只是其中的很小的一部分。但本文中介绍的二个示例在功能上虽不复杂,但在结构上却非常典型,Socket类的其他方面的应用在结构上大都也是如此。
在上面介绍的内容中,不仅介绍在Visual C#实现端口侦听、网络连接申请、数据发送、数据接收的具体方法,还介绍了在使用Visual C#实现网络功能是所必然要涉及到的如线程创建、线程销毁、资源回收和利用控制码控制程序运行状态等的实现方法。了解并掌握这些对我们编写功能更强、结构更复杂的网络应用程序是非常有帮助的。
最后要和诸位朋友谈一点小体会,就是在编写网络应用程序时,要非常细心,对应用程序在执行的各个环节都要考虑到位,因为在网络中会出现很多意想不到的问题,就是网络状态非常良好,也存在很多使用者方面的问题。如果在编写的程序中缺乏对这些意外的处理,就可能会导致整个应用程序出错,甚至崩溃。
Visual C#在使用Socket来介绍网络传送来的数据时,要解决下面三个问题,也是完成Visual C#使用Socket来接收数据的三个步骤:
1.侦听网络,接受网络连接申请;
2..获得用以接收数据的Socket实例,并以此实例接收远程主机发送来的数据;
3.根据远程主机发送来的控制码,断开网络连接,并清除资源。
此处接收接收数据,是上面介绍的【利用Socket来传送数据】传送来的数据。
下面就是利用Socket来接收数据的具体实现步骤:
1.启动Viisual Studio .Net,并新建一个Visual C#项目,项目名称为【利用Socket来接收数据】。
2.把Visual Studio .Net的当前窗口切换到【Form1.cs(设计)】窗口,并从【工具箱】中的【Windows窗体组件】选项卡中往Form1窗体中拖入下列组件,并执行相应操作:
一个ListBox组件,用以显示接收的数据。
一个StausBar组件,用以显示接收端程序的运行状况。
一个Button组件,名称为button1,并在这个组件被拖入窗体后,双击它,则系统会在Form1.cs文件中自动产生其Click事件对应的处理代码。
3.【解决方案资源管理器】窗口中,双击Form1.cs文件,进入Form1.cs文件的编辑界面。
4.以下面代码替代系统产生的InitializeComponent过程::
private void InitializeComponent ( ) { this.button1 = new System.Windows.Forms.Button ( ) ; this.listBox1 = new System.Windows.Forms.ListBox ( ) ; this.statusBar1 = new System.Windows.Forms.StatusBar ( ) ; this.SuspendLayout ( ) ; this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat ; this.button1.Location = new System.Drawing.Point ( 96 , 16 ) ; this.button1.Name = "button1" ; this.button1.Size = new System.Drawing.Size ( 80 , 34 ) ; this.button1.TabIndex = 0 ; this.button1.Text = "监听" ; this.button1.Click += new System.EventHandler ( this.button1_Click ) ; this.listBox1.ItemHeight = 12 ; this.listBox1.Location = new System.Drawing.Point ( 16 , 68 ) ; this.listBox1.Name = "listBox1" ; this.listBox1.Size = new System.Drawing.Size ( 258 , 172 ) ; this.listBox1.TabIndex = 1 ; this.statusBar1.Location = new System.Drawing.Point ( 0 , 251 ) ; this.statusBar1.Name = "statusBar1" ; this.statusBar1.Size = new System.Drawing.Size ( 292 , 22 ) ; this.statusBar1.TabIndex = 2 ; this.statusBar1.Text = "无连接" ; this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ; this.ClientSize = new System.Drawing.Size ( 292 , 273 ) ; this.Controls.AddRange ( new System.Windows.Forms.Control[] { this.statusBar1 , this.listBox1 , this.button1} ) ; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle ; this.MaximizeBox = false ; this.Name = "Form1" ; this.Text = "利用Socket来接收数据" ; this.ResumeLayout ( false ) ; } |
至此【利用Socket来接收数据】项目设计后的界面就完成了,具体如图02所示:

图02:【利用Socket来接收数据】项目的设计界面
5.把Visual Studio .Net的当前窗口切换到Form1.cs的代码编辑窗口,并在Form1.cs文件的开头,用下列导入命名空间代码替代系统缺省的导入命名空间代码。
using System ; using System.Drawing ; using System.Collections ; using System.ComponentModel ; using System.Windows.Forms ; using System.Data ; using System.Net.Sockets ; //使用到TcpListen类 using System.Net ; using System.Threading ; //使用到线程 |
6.在Form1.cs中的class代码区中添加下列代码,下列代码的作用是定义全局变量和创建全局使用的实例:
int port = 8000 ; //定义侦听端口号 private Thread thThreadRead ; //创建线程,用以侦听端口号,接收信息 private TcpListener tlTcpListen ; //侦听端口号 private bool blistener = true ; //设定标示位,判断侦听状态 private Socket stRead ; |
{ try { tlTcpListen = new TcpListener ( port ) ; //以8000端口号来初始化TcpListener实例 tlTcpListen.Start ( ) ; //开始监听网络的连接请求 statusBar1.Text = "正在监听..." ; stRead = tlTcpListen.AcceptSocket ( ) ; //通过连接请求,并获得接收数据时使用的Socket实例 EndPoint tempRemoteEP = stRead.RemoteEndPoint ; IPEndPoint tempRemoteIP = ( IPEndPoint ) tempRemoteEP ; //获取请求的远程计算机名称 IPHostEntry host = Dns.GetHostByAddress ( tempRemoteIP.Address ) ; string sHostName = host.HostName ; statusBar1.Text = "已经连接!" ; //循环侦听 while ( blistener ) { string sTime = DateTime.Now.ToShortTimeString ( ) ; //获取接收数据时的时间 Byte [ ] byRead =new Byte [ 80 ] ; int iRead = stRead.ReceiveFrom ( byRead , ref tempRemoteEP ) ; //获得接收的字节数目 Byte [ ] byText = new Byte [ iRead ] ; //并根据接收到的字节数目来定义字节数组 Array.Copy ( byRead , 0 , byText , 0 , iRead ) ; string sTemp = System.Text.Encoding.Default. GetString ( byText ) ; //判断是否为断开连接控制码 if ( sTemp.Trim ( ) == "STOP" ) { stRead.Close ( ) ; tlTcpListen.Stop ( ) ; //关闭侦听 statusBar1.Text = "连接已经关闭!" ; thThreadRead.Abort ( ) ; //中止线程 return ; } else listBox1.Items.Add ( sTime + " " + sTemp ) ; } catch ( System.Security.SecurityException ) { MessageBox.Show ( "侦听失败!" , "错误" ) ; } } |
8.用下列代码替换Form1.cs中的button1组件的Click事件对应的处理代码,下面代码是以刚刚定义“Listen”过程来初始化线程实例thThreadRead,并启动这个线程:
private void button1_Click ( object sender , System.EventArgs e ) { thThreadRead = new Thread ( new ThreadStart ( Listen ) ) ; //以Listen过程来初始化Thread实例 thThreadRead.Start ( ) ; //启动线程 button1.Enabled = false ; } |
至此,在保存上述的所有修改步骤之后。一个基于TCP协议的、利用Socket接收端程序的就完成了。图03和图04分别是上述二个示例运行后的界面

图03:【利用Socket来传送数据】的运行界面

图04:【利用Socket来接收数据】的运行界面
六.总结:
.Net FrameWork SDK中的Socket类的功能是非常强大的,要十分详细的介绍它,非一篇文章所能达到,本文所窥探的也只是其中的很小的一部分。但本文中介绍的二个示例在功能上虽不复杂,但在结构上却非常典型,Socket类的其他方面的应用在结构上大都也是如此。
在上面介绍的内容中,不仅介绍在Visual C#实现端口侦听、网络连接申请、数据发送、数据接收的具体方法,还介绍了在使用Visual C#实现网络功能是所必然要涉及到的如线程创建、线程销毁、资源回收和利用控制码控制程序运行状态等的实现方法。了解并掌握这些对我们编写功能更强、结构更复杂的网络应用程序是非常有帮助的。
最后要和诸位朋友谈一点小体会,就是在编写网络应用程序时,要非常细心,对应用程序在执行的各个环节都要考虑到位,因为在网络中会出现很多意想不到的问题,就是网络状态非常良好,也存在很多使用者方面的问题。如果在编写的程序中缺乏对这些意外的处理,就可能会导致整个应用程序出错,甚至崩溃。